symfony/polyfill
Symfony Polyfill backports newer PHP features and provides compatibility layers for missing extensions and functions. Use it to keep apps portable across PHP versions, smoothing gaps in intl, mbstring/iconv, uuid, and many core APIs.
Identify Required Polyfills:
Check your php -r "echo PHP_VERSION;" and missing extensions (e.g., mbstring, intl). Use the README to map features to standalone packages (e.g., symfony/polyfill-mbstring for mbstring functions).
Install via Composer:
composer require symfony/polyfill-mbstring symfony/polyfill-php80
Replace with the specific polyfills needed (e.g., symfony/polyfill-intl-idn for idn_to_ascii).
First Use Case:
Use PHP 8.0+ functions like str_contains() in PHP 7.4:
use Symfony\Polyfill\String\Stringable;
$stringable = new Stringable('hello');
$contains = $stringable->contains('ell'); // true
array_key_first() in PHP 7.3+:
use Symfony\Polyfill\Php73\array_key_first;
$keys = array_key_first(['a' => 1, 'b' => 2]); // 'a'
mbstring) with polyfills.mb_strlen() without the mbstring extension:
use Symfony\Polyfill\Mbstring\Mbstring;
$length = Mbstring\mb_strlen('こんにちは'); // 5
Stringable for str_contains).composer.json:
"replace": {
"symfony/polyfill-php73": "*" // Skip if PHP ≥ 7.3
}
Stringable to a helper:
use Symfony\Polyfill\String\Stringable;
if (!function_exists('str_starts_with')) {
Stringable::register();
}
str_contains in tests:
use Symfony\Polyfill\String\Stringable;
$stringable = new Stringable('test');
$this->assertTrue($stringable->contains('es')); // true
Direct symfony/polyfill Requirement:
symfony/polyfill directly—it bloats dependencies.symfony/polyfill-php80).Extension Conflicts:
mbstring polyfill vs. installed mbstring).replace in composer.json to exclude polyfills when extensions are available.Closure Deep Cloning:
deepclone polyfill may fail with closures or complex objects.DEEPCLONE_HYDRATE_PRESERVE_REFS flag for circular references:
use Symfony\Polyfill\DeepClone\deepclone;
$cloned = deepclone($obj, DEEPCLONE_HYDRATE_PRESERVE_REFS);
UTF-8 Handling:
mbstring) may misbehave with invalid UTF-8.mb_check_encoding() or iconv.Performance Overhead:
replace or autoload-dev.Check Polyfill Registration:
if (!function_exists('str_contains')) {
throw new \RuntimeException('Polyfill not loaded!');
}
Extension Detection:
if (!extension_loaded('mbstring')) {
echo 'Install mbstring or use polyfill.';
}
Deep Clone Issues:
try {
$cloned = deepclone($obj);
} catch (\Exception $e) {
var_dump($e->getMessage());
}
Custom Polyfills:
Stringable).str_contains wrapper:
class CustomStringable extends Stringable {
public function containsIgnoreCase(string $needle): bool {
return str_contains(strtolower($this->string), strtolower($needle));
}
}
Bootstrap Optimization:
vendor/autoload.php to load only needed polyfills:
require __DIR__.'/symfony/polyfill-php80/Resources/stubs/stringable.php';
PHP 8 Attributes:
#[Attribute]) in PHP < 8.0:
use Symfony\Polyfill\Php80\Attribute\Attribute;
#[Attribute]
class CustomAttribute {}
Service Provider Registration:
AppServiceProvider:
public function boot() {
if (!function_exists('str_contains')) {
Stringable::register();
}
}
Blade Directives:
@php
use Symfony\Polyfill\String\Stringable;
$stringable = new Stringable('hello');
@endphp
Artisan Commands:
use Symfony\Polyfill\Php80\Stringable;
class MyCommand extends Command {
protected function handle() {
Stringable::register();
// Use str_contains() here
}
}
How can I help you explore Laravel packages today?