symfony/polyfill-php81
Symfony Polyfill for PHP 8.1 features on older runtimes. Adds array_is_list, enum_exists, MYSQLI_REFRESH_REPLICA, ReturnTypeWillChange, and CURLStringFile (PHP 7.4+). Drop-in Composer dependency for wider compatibility.
Installation: Add the polyfill via Composer:
composer require symfony/polyfill-php81
For development/testing only:
composer require --dev symfony/polyfill-php81
First Use Case:
Replace manual array validation with array_is_list in Laravel’s validation logic (e.g., API request payloads):
use Symfony\Polyfill\Php81\Php81;
$payload = [1, 2, 3];
if (Php81\array_is_list($payload)) {
// Process sequential array
}
Where to Look First:
array_is_list edge cases).Validation Layers:
Replace custom sequential array checks with array_is_list in Laravel’s FormRequest or API validation:
public function rules()
{
return [
'data' => ['required', function ($attribute, $value, $fail) {
if (!Php81\array_is_list($value)) {
$fail('The :attribute must be a sequential array.');
}
}],
];
}
Domain Models with Enums:
Use enum_exists and enums in Laravel models (PHP 7.4–8.0):
use Symfony\Polyfill\Php81\Php81;
if (Php81\enum_exists('App\Models\PaymentStatus')) {
// Safe to use enums
$status = PaymentStatus::PENDING;
}
HTTP/File Operations:
Leverage CURLStringFile for file uploads in legacy Laravel branches:
$file = new \Symfony\Polyfill\Php81\Curl\CurlFile('/path/to/file', 'text/plain');
$response = Http::post('https://api.example.com/upload', [
'file' => $file,
]);
Internal Method Refactoring:
Annotate methods with @return void using ReturnTypeWillChange during PHP 8.1 migration prep:
/**
* @return void
* @deprecated Use native return type declarations in PHP 8.1+
*/
public function legacyMethod()
{
# ReturnTypeWillChange annotation (handled by polyfill)
}
Feature-Flagged Adoption: Wrap polyfill usage in feature flags for gradual rollout:
if (feature_enabled('php81_polyfills')) {
if (Php81\array_is_list($data)) { ... }
} else {
// Fallback logic
}
Testing Strategy:
$this->mock(Php81::class)
->shouldReceive('array_is_list')
->andReturnTrue();
Performance Profiling: Benchmark polyfilled functions in critical paths (e.g., API routes) using:
php -d memory_limit=-1 vendor/bin/phpunit --testdox --filter=PerformanceTest
Laravel Service Providers:
Register polyfill-aware services in AppServiceProvider:
public function boot()
{
if (Php81\enum_exists('App\Models\UserRole')) {
$this->app->bind('role_resolver', UserRoleResolver::class);
}
}
Custom Validation Rules: Extend Laravel’s validator with polyfill-aware rules:
Validator::extend('is_sequential_array', function ($attribute, $value, $parameters) {
return Php81\array_is_list($value);
});
PHPStan/Psalm Integration: Configure static analyzers to recognize polyfilled types:
# phpstan.neon
parameters:
level: 8
includePhp: true
polyfillPhp81: true
False Positives in array_is_list:
true for arrays with null values (e.g., [null, 1, 2]), unlike PHP 8.1’s stricter behavior.if (Php81\array_is_list($array) && !in_array(null, $array)) { ... }
Enum Behavior Differences:
enum_exists may not replicate PHP 8.1’s case-sensitive checks.strtolower for enum names:
if (Php81\enum_exists(strtolower('App\Models\PaymentStatus'))) { ... }
ReturnTypeWillChange Overhead:
PHP 8.1+ Conflicts:
composer remove symfony/polyfill-php81
Composer Autoload Issues:
composer dump-autoload is skipped.composer dump-autoload --optimize
Polyfill Not Loading:
var_dump(class_exists('Symfony\Polyfill\Php81\Php81'));
symfony/polyfill-php81 is in composer.json and autoloaded.Performance Bottlenecks:
php -dxdebug.mode=profile -dxdebug.output_dir=/tmp app/Artisan tinker
Enum Serialization Issues:
$encoder = new JsonEncoder();
$encoder->encode($enumInstance->value);
Laravel Mix/Webpack:
Environment-Specific Loading:
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
require __DIR__.'/vendor/autoload.php'; // Ensure polyfill is loaded
}
CI/CD Pipeline:
# .github/workflows/tests.yml
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
php: ['7.4', '8.0', '8.1']
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- run: composer install
- run: php artisan test
Custom Polyfill Logic:
$this->app->singleton('array_is_list', function () {
return function ($array) {
// Custom implementation
return array_keys($array) === range(0, count($array) - 1);
};
});
Laravel Facade Integration:
// app/Facades/Polyfill.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
use Symfony\Polyfill\Php81\Php81;
class Polyfill extends Facade
{
public static function getFacadeAccessor()
{
return Php81::class;
}
}
Usage:
if (Polyfill::array_is_list($data)) { ... }
**Dynamic Feature
How can I help you explore Laravel packages today?