← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

PHP Intl Extension

i18n PHP 5.3+ Intermediate
debt(d5/e3/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches' (d5). PHPStan and Psalm (cited in detection_hints.tools) can detect patterns like number_format() instead of NumberFormatter or sorting without Collator, but these require static analysis configuration and aren't default linter rules — they need intentional setup to catch i18n anti-patterns.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix indicates replacing native functions with Intl equivalents: number_format() → NumberFormatter, sort() → Collator::sort(), date format → IntlDateFormatter. Each is a localised swap within components handling formatting/sorting, not a one-liner but not cross-cutting either.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). The applies_to shows this affects all PHP contexts (web, cli), and i18n choices tend to be pervasive — once you've chosen to use native sort() and number_format() throughout, every new feature involving sorting or number display must remember to use Intl classes instead. It's not architectural but creates ongoing friction.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception states explicitly that PHP's native sort() appears to work but silently produces wrong results for accented characters — this contradicts expectations from ASCII-centric development where sort() 'just works'. A competent developer unfamiliar with Unicode collation will assume native functions handle strings correctly, only to discover French users see mangled alphabetical order.

About DEBT scoring →

Also Known As

PHP Intl ICU PHP MessageFormatter Collator IntlDateFormatter

TL;DR

PHP's built-in internationalisation extension wrapping ICU — MessageFormatter, Collator, NumberFormatter, DateFormatter, and Normalizer for correct multilingual handling.

Explanation

The PHP Intl extension wraps ICU (International Components for Unicode). Key classes: MessageFormatter (ICU message format with plurals, selects, number formatting), Collator (locale-aware string sorting — essential for accented characters), NumberFormatter (currency, percentage, decimal with locale-specific formatting), IntlDateFormatter (locale-aware date/time formatting), and Normalizer (Unicode normalisation — NFC, NFD, NFKC). Required for: sorting strings with accented characters correctly, formatting numbers and dates for different locales, and complex plural rules. Install: typically included with PHP; may need php-intl package.

Common Misconception

PHP's native sort() works for all languages — sort() uses byte comparison which gives wrong order for accented characters; Collator::sort() applies locale-specific collation rules correctly.

Why It Matters

Sorting a French word list with PHP's sort() puts all accented words after all ASCII words — Collator with the fr locale sorts them correctly according to French alphabetical conventions.

Common Mistakes

  • sort() for locale-aware string sorting — use Collator.
  • number_format() for currency — use NumberFormatter which handles locale-specific symbols and formatting.
  • DateTimeImmutable::format() for user-facing dates — use IntlDateFormatter for locale-aware output.
  • Not normalising Unicode input — the same character can have multiple representations (é as one code point or e + combining accent).

Code Examples

✗ Vulnerable
// PHP native — locale-unaware:
sort($frenchWords); // 'é' sorts after 'z' — wrong for French
number_format(1234567.89, 2, '.', ','); // '1,234,567.89' wrong for German (needs '1.234.567,89')
echo $date->format('d/m/Y'); // UK format served to US user — ambiguous
✓ Fixed
// PHP Intl — locale-aware:
$collator = new Collator('fr_FR');
$collator->sort($frenchWords); // Correct French alphabetical order

$numFmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
echo $numFmt->formatCurrency(1234567.89, 'EUR'); // '1.234.567,89 €'

$dateFmt = new IntlDateFormatter(
    'en_US',
    IntlDateFormatter::LONG,
    IntlDateFormatter::NONE,
    'America/New_York'
);
echo $dateFmt->format(new DateTime('2026-03-16')); // 'March 16, 2026'

// Normalize unicode:
$normalised = Normalizer::normalize($input, Normalizer::NFC);

Added 16 Mar 2026
Edited 22 Mar 2026
Views 32
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 9 Perplexity 8 Unknown AI 3 Ahrefs 2 Google 2 ChatGPT 1 Qwen 1
crawler 24 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Use PHP's Intl extension (ICU-based) for locale-aware operations — NumberFormatter for prices, DateFormatter for dates, MessageFormatter for pluralisation, Collator for sorting
📦 Applies To
PHP 5.3+ web cli
🔗 Prerequisites
🔍 Detection Hints
Number formatted with number_format() instead of NumberFormatter; date formatted without locale; sorting strings with usort instead of Collator
Auto-detectable: ✓ Yes phpstan psalm
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update

✓ schema.org compliant