Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Intl Laravel Package

symfony/intl

Symfony Intl component provides access to ICU localization data in PHP: locales, languages, scripts, regions, currencies, and more. Includes tooling to compress bundled data (with zlib) for smaller installs and faster lookups.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package:

    composer require symfony/intl
    

    For compressed ICU data (recommended for production):

    php vendor/symfony/intl/Resources/bin/compress
    
  2. First Use Case: Localized Number Formatting

    use Symfony\Component\Intl\NumberFormatter;
    
    $formatter = NumberFormatter::create('en_US', NumberFormatter::CURRENCY);
    echo $formatter->format(1234.56); // Output: "$1,234.56"
    
    $formatter = NumberFormatter::create('de_DE', NumberFormatter::CURRENCY);
    echo $formatter->format(1234.56); // Output: "1.234,56 €"
    
  3. Key Entry Points:

    • NumberFormatter: For currencies, decimals, and percentages.
    • DateFormatter: For localized dates/times.
    • IntlDateFormatter: Advanced date formatting (e.g., calendars).
    • Locale: Validate and normalize locale strings.
    • Transliterator: Emoji/character transliteration.

Implementation Patterns

Core Workflows

1. Localized Number/Currency Handling

Pattern: Use NumberFormatter with Laravel’s app() helper for dependency injection.

use Symfony\Component\Intl\NumberFormatter;

// In a Laravel service/controller:
$formatter = app(NumberFormatter::class)->create('ja_JP', NumberFormatter::CURRENCY);
$formatted = $formatter->format(1000); // "¥1,000"

Integration Tip: Store formatted values in a formatted_value column in the DB (e.g., for e-commerce) and cache results with Illuminate\Support\Facades\Cache.

2. Dynamic Locale Detection

Pattern: Combine with Laravel’s Request to auto-detect user locale.

use Symfony\Component\Intl\Locale;

$locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
$formatter = NumberFormatter::create($locale, NumberFormatter::DECIMAL);

Workflow:

  1. Detect locale via Request::getPreferredLanguage() (Laravel 9+) or Accept-Language header.
  2. Fallback to app()->getLocale() if unsupported.
  3. Cache formatter instances by locale (e.g., Cache::remember("formatter_{$locale}", ...)).

3. Date/Time Localization

Pattern: Use DateFormatter for user-facing dates.

use Symfony\Component\Intl\DateFormatter;

$date = new \DateTime('2023-12-25');
$formatter = DateFormatter::create(
    'ar_EG', // Arabic (Egypt)
    DateFormatter::LONG,
    DateFormatter::LONG,
    'Asia/Cairo',
    DateFormatter::GREGORIAN
);
echo $formatter->format($date); // "25 ديسمبر 2023"

Integration Tip: Create a Laravel macro for Carbon:

use Carbon\Carbon;
use Symfony\Component\Intl\DateFormatter;

Carbon::macro('formatLocalized', function (string $locale, string $format = DateFormatter::LONG) {
    $formatter = DateFormatter::create($locale, $format, $format);
    return $formatter->format($this);
});

Usage:

Carbon::now()->formatLocalized('fr_FR'); // "25 décembre 2023"

4. Pluralization Rules

Pattern: Use IntlPluralRules for grammatically correct UI.

use Symfony\Component\Intl\IntlPluralRules;

$rules = IntlPluralRules::create('ru_RU');
$count = 5;
$rule = $rules->select($count);
// Output: "one", "few", "many", or "other"

Use Case: Dynamic messages like:

$message = match ($rule) {
    'one' => '1 элемент',
    default => "$count элементов",
};

5. Emoji/Character Transliteration

Pattern: Convert emoji to text for compatibility.

use Symfony\Component\Intl\Transliterator;

$transliterator = Transliterator::create('Any-Latin; Latin-ASCII');
echo $transliterator->transliterate('Hello 👋'); // "Hello [hand]"

Integration Tip: Sanitize user input (e.g., comments) to remove unsupported emoji.


Laravel-Specific Patterns

1. Service Provider Binding

Register formatters as Laravel services:

// app/Providers/AppServiceProvider.php
use Symfony\Component\Intl\NumberFormatter;

public function register()
{
    $this->app->singleton(NumberFormatter::class, function () {
        return new NumberFormatter('en_US', NumberFormatter::CURRENCY);
    });
}

Dynamic Binding:

$this->app->bind(NumberFormatter::class, function ($app, $locale) {
    return new NumberFormatter($locale, NumberFormatter::CURRENCY);
});

Usage:

$formatter = app(NumberFormatter::class, 'ja_JP');

2. Blade Directives

Create a Blade directive for localized formatting:

// app/Providers/BladeServiceProvider.php
use Illuminate\Support\Facades\Blade;

Blade::directive('localize', function ($locale) {
    return "<?php echo app(\\Symfony\\Component\\Intl\\NumberFormatter::class, '{$locale}')->format(";
});

Usage in Blade:

@localize('de_DE')(1234.56) @endlocalize

3. Validation Rules

Extend Laravel’s validation with Intl rules:

use Illuminate\Validation\Rule;
use Symfony\Component\Intl\Locale;

Rule::macro('validLocale', function ($locale = null) {
    return function ($attribute, $value, $fail) use ($locale) {
        if (!Locale::acceptFromHttp($value) && !$locale) {
            $fail('The :attribute must be a valid locale.');
        }
    };
});

Usage:

'locale' => ['required', 'validLocale'],

4. API Responses

Format responses dynamically:

use Symfony\Component\Intl\NumberFormatter;

return response()->json([
    'price' => [
        'raw' => 1234.56,
        'formatted' => app(NumberFormatter::class, request()->locale)->format(1234.56),
    ],
]);

Gotchas and Tips

Pitfalls

1. Locale Fallbacks

  • Gotcha: Missing locales throw exceptions. Always validate:
    if (!Locale::hasLocale($locale)) {
        $locale = app()->getLocale(); // Fallback
    }
    
  • Tip: Use Locale::getRegion() to check if a locale is supported before formatting.

2. ICU Data Compression

  • Gotcha: Compressed data (compress command) must match your PHP environment’s ICU version. Re-run compression after updating PHP/ICU.
  • Tip: Test compression in staging:
    php vendor/symfony/intl/Resources/bin/compress --test
    

3. Time Zone Handling

  • Gotcha: DateFormatter requires IANA time zones (e.g., America/New_York). Avoid generic names like EST.
  • Tip: Use Laravel’s Carbon to normalize time zones:
    $date = Carbon::now()->timezone('Asia/Tokyo');
    

4. Emoji Transliteration

  • Gotcha: Transliterator may not support all emoji. Test edge cases (e.g., skin tones, regional indicators).
  • Tip: Fallback to a static mapping for unsupported emoji:
    $transliterator = Transliterator::create('Any-Latin');
    $text = $transliterator->transliterate($input);
    $text = preg_replace('/\[([^\]]+)\]/', '[EMOJI:$1]', $text);
    

5. Performance with Many Locales

  • Gotcha: Creating a NumberFormatter per request for dynamic locales is slow. Cache instances:
    Cache::remember("formatter_{$locale}", now()->addHours(1), function () use ($locale) {
        return NumberFormatter::create($locale, NumberFormatter::
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata