symfony/polyfill-intl-icu
Fallback implementations for PHP’s Intl ICU features when the intl extension isn’t installed. Provides limited “en” locale support for intl error functions plus Collator, NumberFormatter, Locale, IntlDateFormatter and IntlListFormatter.
Install the Package:
composer require symfony/polyfill-intl-icu:^1.34.0
No additional configuration is required—Laravel’s autoloader handles the polyfill automatically.
First Use Case: RTL Detection Check if a locale is right-to-left (e.g., Arabic, Hebrew) in a Blade view or controller:
use Symfony\Component\Polyfill\Intl\Icu\Locale as PolyfillLocale;
$isRtl = PolyfillLocale::isRightToLeft('ar'); // true for RTL locales
Use this to dynamically apply RTL CSS classes in your frontend framework (e.g., Tailwind, Bootstrap).
First Use Case: Basic Formatting
Use NumberFormatter or IntlDateFormatter without the intl extension:
use Symfony\Component\Polyfill\Intl\Icu\NumberFormatter as PolyfillNumberFormatter;
$formatter = new PolyfillNumberFormatter('en_US', NumberFormatter::CURRENCY);
echo $formatter->format(1234.56); // Outputs: $1,234.56
Verify Polyfill Activation
Check if the intl extension is loaded (polyfill activates automatically if not):
if (!extension_loaded('intl')) {
// Polyfill is active; proceed with ICU classes.
}
Pattern: Dynamically apply RTL styles based on locale.
// In a Laravel controller or service
public function getRtlStatus($locale)
{
return PolyfillLocale::isRightToLeft($locale);
}
Frontend Integration (Blade):
@php
$isRtl = \Symfony\Component\Polyfill\Intl\Icu\Locale::isRightToLeft(app()->getLocale());
@endphp
<div class="{{ $isRtl ? 'rtl' : 'ltr' }}">
<!-- RTL/LTR content -->
</div>
Pattern: Use IntlListFormatter for localized list patterns (e.g., "A, B, and C").
use Symfony\Component\Polyfill\Intl\Icu\IntlListFormatter;
$formatter = new IntlListFormatter('en', IntlListFormatter::LONG);
$list = $formatter->format(['Apple', 'Banana', 'Cherry']); // "Apple, Banana, and Cherry"
Laravel Integration:
Pattern: Use Collator for basic sorting when intl is unavailable.
use Symfony\Component\Polyfill\Intl\Icu\Collator;
$collator = new Collator('en');
$result = $collator->compare('apple', 'banana'); // -1 (English collation)
Laravel Integration:
Model::orderByRaw() with collator results).Pattern: Format dates or numbers with IntlDateFormatter or NumberFormatter.
use Symfony\Component\Polyfill\Intl\Icu\IntlDateFormatter;
$dateFormatter = new IntlDateFormatter(
'en_US',
IntlDateFormatter::LONG,
IntlDateFormatter::NONE,
'America/New_York',
IntlDateFormatter::GREGORIAN
);
echo $dateFormatter->format(time()); // "March 5, 2023"
Laravel Integration:
translatedFormat() for non-English locales (if intl is unavailable).Gracefully handle cases where the intl extension becomes available later:
if (extension_loaded('intl')) {
// Use native Intl classes for better performance.
$formatter = new \NumberFormatter('en_US');
} else {
// Fallback to polyfill.
$formatter = new \Symfony\Component\Polyfill\Intl\Icu\NumberFormatter('en_US');
}
Bind the polyfill classes to Laravel’s service container for dependency injection:
// In AppServiceProvider@boot()
$this->app->bind(
\Symfony\Component\Polyfill\Intl\Icu\Collator::class,
function ($app) {
return new \Symfony\Component\Polyfill\Intl\Icu\Collator('en');
}
);
Now inject Collator into controllers/services:
public function __construct(private Collator $collator) {}
Cache expensive operations (e.g., Collator::compare() for large datasets):
$cacheKey = 'collator_compare_' . md5($str1 . $str2);
$result = cache()->remember($cacheKey, now()->addHours(1), function () use ($collator, $str1, $str2) {
return $collator->compare($str1, $str2);
});
Mock the polyfill in tests to simulate environments without intl:
use Symfony\Component\Polyfill\Intl\Icu\Collator;
public function testCollatorWithoutIntl()
{
$collator = new Collator('en');
$this->assertEquals(-1, $collator->compare('apple', 'banana'));
}
Leverage IntlListFormatter in PHP 8.5:
if (version_compare(PHP_VERSION, '8.5.0', '>=')) {
$formatter = new \Symfony\Component\Polyfill\Intl\Icu\IntlListFormatter('en');
$list = $formatter->format(['Item 1', 'Item 2']);
}
NumberFormatter/IntlDateFormatter instances will use English patterns (e.g., en_US dates for fr_FR locales).if (app()->getLocale() !== 'en') {
throw new \RuntimeException('Non-English locales require the intl extension.');
}
intl for operations like Collator::compare() or IntlListFormatter::format().Collator::compare() may not handle mixed-script strings (e.g., Arabic + Latin) correctly. The polyfill’s fallback is simplistic.['apple', 'أبل', 'banana']).intl if mixed-script sorting is critical.IntlListFormatter is supported in PHP 8.5, edge cases (e.g., custom list patterns) may not work as expected.locale_is_right_to_left() may not align with your frontend framework’s RTL detection (e.g., Tailwind’s rtl class logic).ar, he, fa, ur) and adjust UI logic accordingly.intl is available.Verify if the polyfill is active:
if (!extension
How can I help you explore Laravel packages today?