IntlPull
Tutorial
16 min read

PHP Localization: Complete Array-Based i18n Guide (2026)

Master PHP internationalization with array-based translations. Learn setup, best practices, pluralization, date formatting, and integration with Laravel, Symfony, and WordPress.

IntlPull Team
IntlPull Team
09 Feb 2026, 10:19 AM [PST]
On this page
Summary

Master PHP internationalization with array-based translations. Learn setup, best practices, pluralization, date formatting, and integration with Laravel, Symfony, and WordPress.

Quick Answer

To localize a PHP application, use array-based translation files. Store translations in PHP arrays (/lang/en/messages.php), create a translation helper function, and use it throughout your app. For frameworks: Laravel has built-in __('key') helper, Symfony uses Translation component, WordPress uses __('text', 'domain'). This approach is simple, fast, and works with any PHP version.


Why PHP Localization Matters

PHP powers 77% of websites (W3Techs, 2026). From WordPress to Laravel, PHP applications serve global audiences.

The challenge: PHP doesn't have built-in i18n like JavaScript frameworks. You need to implement it yourself or use a framework's solution.

The solution: Array-based translations are the PHP standard. Simple, performant, and framework-agnostic.


Basic Setup: Plain PHP

Step 1: Create Translation Files

Directory structure:

/lang
  /en
    messages.php
    validation.php
  /es
    messages.php
    validation.php
  /fr
    messages.php
    validation.php

lang/en/messages.php:

PHP
1<?php
2
3return [
4    'welcome' => 'Welcome to our application',
5    'goodbye' => 'Goodbye, :name!',
6    'items_count' => '{0} No items|{1} One item|[2,*] :count items',
7    
8    // Nested arrays for organization
9    'auth' => [
10        'login' => 'Log in',
11        'logout' => 'Log out',
12        'register' => 'Sign up',
13        'failed' => 'These credentials do not match our records.',
14    ],
15    
16    'nav' => [
17        'home' => 'Home',
18        'about' => 'About Us',
19        'contact' => 'Contact',
20    ],
21];

Laravel Localization

Laravel has built-in localization. It's the same array-based approach, but with more features.

Setup

1. Create translation files:

/lang
  /en
    messages.php
    validation.php
  /es
    messages.php
    validation.php

2. Configure default locale:

PHP
1// config/app.php
2
3'locale' => 'en',
4'fallback_locale' => 'en',
5'available_locales' => ['en', 'es', 'fr', 'de'],

3. Use in views:

PHP
1<!-- Blade template -->
2<h1>{{ __('messages.welcome') }}</h1>
3<p>{{ __('messages.goodbye', ['name' => $user->name]) }}</p>
4
5<!-- Pluralization -->
6<p>{{ trans_choice('messages.items_count', $count) }}</p>
7
8<!-- Short syntax (Laravel 9+) -->
9<h1>@lang('messages.welcome')</h1>

4. Use in controllers:

PHP
1<?php
2
3namespace AppHttpControllers;
4
5class HomeController extends Controller
6{
7    public function index()
8    {
9        // Get translation
10        $message = __('messages.welcome');
11        
12        // With replacements
13        $greeting = __('messages.goodbye', ['name' => 'John']);
14        
15        // Pluralization
16        $items = trans_choice('messages.items_count', 5);
17        
18        return view('home', compact('message', 'greeting', 'items'));
19    }
20}

5. Change locale dynamically:

PHP
1<?php
2
3// In middleware or controller
4App::setLocale('es');
5
6// Get current locale
7$locale = App::getLocale();
8
9// Check if locale is available
10if (in_array($locale, config('app.available_locales'))) {
11    App::setLocale($locale);
12}

Symfony Translation Component

Symfony has a powerful Translation component that works standalone or with the framework.

Installation (Standalone)

Terminal
composer require symfony/translation

Setup

PHP
1<?php
2
3use SymfonyComponentTranslationTranslator;
4use SymfonyComponentTranslationLoaderPhpFileLoader;
5
6$translator = new Translator('en');
7$translator->setFallbackLocales(['en']);
8
9// Add loader for PHP files
10$translator->addLoader('php', new PhpFileLoader());
11
12// Load translation files
13$translator->addResource('php', __DIR__ . '/lang/en/messages.php', 'en', 'messages');
14$translator->addResource('php', __DIR__ . '/lang/es/messages.php', 'es', 'messages');
15
16// Use translations
17echo $translator->trans('welcome', [], 'messages'); // "Welcome to our application"
18
19// With replacements
20echo $translator->trans('goodbye', ['%name%' => 'John'], 'messages'); // "Goodbye, John!"

WordPress Localization

WordPress uses gettext, but you can also use array-based translations.

Traditional WordPress Way (Gettext)

1. Mark strings for translation:

PHP
1<?php
2
3// In theme or plugin
4echo __('Welcome to our site', 'my-theme');
5echo _e('Hello World', 'my-theme'); // Echo directly
6
7// With variables
8printf(__('Hello, %s!', 'my-theme'), $name);
9
10// Pluralization
11echo _n('%s item', '%s items', $count, 'my-theme');

2. Generate .pot file:

Terminal
1# Using WP-CLI
2wp i18n make-pot . languages/my-theme.pot
3
4# Or use Poedit to scan files

Date and Number Formatting

Using PHP Intl Extension

PHP
1<?php
2
3$locale = 'es_ES';
4
5// Date formatting
6$formatter = new IntlDateFormatter(
7    $locale,
8    IntlDateFormatter::LONG,
9    IntlDateFormatter::NONE
10);
11echo $formatter->format(new DateTime()); // "7 de febrero de 2026"
12
13// Number formatting
14$numberFormatter = new NumberFormatter($locale, NumberFormatter::DECIMAL);
15echo $numberFormatter->format(1234.56); // "1.234,56"
16
17// Currency formatting
18$currencyFormatter = new NumberFormatter($locale, NumberFormatter::CURRENCY);
19echo $currencyFormatter->formatCurrency(1234.56, 'EUR'); // "1.234,56 €"

Best Practices

1. Organize Translation Files

/lang
  /en
    messages.php       # General UI strings
    validation.php     # Form validation messages
    auth.php          # Authentication messages
    emails.php        # Email templates
    errors.php        # Error messages

2. Use Nested Arrays

PHP
1<?php
2
3return [
4    'auth' => [
5        'login' => 'Log in',
6        'logout' => 'Log out',
7        'register' => 'Sign up',
8    ],
9    'nav' => [
10        'home' => 'Home',
11        'about' => 'About',
12    ],
13];
14
15// Usage: __('messages.auth.login')

3. Never Concatenate Translations

PHP
1<?php
2
3// ❌ Bad: Word order differs in languages
4echo __('messages.welcome') . ' ' . $name . '!';
5
6// ✅ Good: Use placeholders
7echo __('messages.welcome_user', ['name' => $name]);

Integration with IntlPull

Setup

Terminal
composer require intlpullhq/php-sdk

Automated Workflow

Terminal
1# Extract strings from code
2php artisan intlpull:extract
3
4# Upload to IntlPull
5php artisan intlpull:upload
6
7# Translate with AI
8php artisan intlpull:translate
9
10# Download translations
11php artisan intlpull:download
12
13# Deploy
14php artisan config:cache

Frequently Asked Questions

Should I use gettext or PHP arrays?

Use PHP arrays for most projects. They're simpler, faster, and don't require PHP extensions. Use gettext only if you need compatibility with existing tools or have translators who prefer .po files.

How do I handle pluralization in PHP?

Use Laravel's trans_choice() or Symfony's trans() with ICU message format. For plain PHP, implement a simple parser that handles {0}, {1}, and [2,*] syntax.

Can I use JSON instead of PHP arrays?

Yes, but PHP arrays are faster. JSON requires parsing on every request. PHP arrays are compiled by OPcache. Use JSON only if you need to share translations with JavaScript.


Conclusion

PHP localization is straightforward with array-based translations.

Quick recap:

  1. Create /lang/{locale}/messages.php files
  2. Return arrays with translation keys
  3. Use __('key') helper function
  4. Handle pluralization with trans_choice()
  5. Format dates/numbers with Intl extension

For production apps:

  • Use Laravel or Symfony for built-in features
  • Integrate with IntlPull for automated workflow
  • Cache translations for performance
  • Follow best practices (nested arrays, placeholders, context)

Try IntlPull Free | View PHP Documentation | Laravel Package

Tags
php
localization
i18n
laravel
symfony
wordpress
internationalization
IntlPull Team
IntlPull Team
Engineering

Building tools to help teams ship products globally. Follow us for more insights on localization and i18n.