October 3, 2014 Javier Eguiluz

If you are a Symfony developer, you have probably suffered the infamous intl problem when installing or deploying Symfony applications. The following error message is the usual symptom of suffering this problem:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 Installing dependencies ( including require-dev ) from lock file Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for symfony/icu v1.2.x -> satisfiable by symfony/icu [ v1.2.x ] . - symfony/icu v1.2.x requires lib-icu > = 4.4 -> the requested linked library icu has the wrong version installed or is missing from your system, make sure to have the extension providing it. Problem 2 - symfony/icu v1.2.x requires lib-icu > = 4.4 -> the requested linked library icu has the wrong version installed or is missing from your system, make sure to have the extension providing it. - symfony/intl v2.5.0 requires symfony/icu ~1.0-RC -> satisfiable by symfony/icu [ v1.2.x ] . - Installation request for symfony/intl v2.5.0 -> satisfiable by symfony/intl [ v2.5.0 ] .

The good news is that in Symfony 2.6 this problem is gone forever. It doesn't matter the way you installed PHP or your specific operating system, you will never see this error again. Moreover, as this problem is so annoying, we've decided to backport it to previous Symfony versions. This means that you won't see this problem again in the new versions of Symfony 2.3 and 2.5. The issue will remain in Symfony 2.4, because that branch is no longer maintained.

"The big picture" of Symfony internationalization¶ To better understand the cause of this problem and its solution, it's important to understand The Big Picture of the projects and systems involved: The CLDR project collects and maintains internationalization data, such as country and language names, currency metadata, number formats, postal code and phone number formats. CLDR data is used in all smartphones, operating systems and important software applications developed by companies such as Apple, Google, Microsoft and IBM.

The ICU project uses the CLDR data and builds C and Java classes on top of them, such as NumberFormatter , IntlDateFormatter , Collator and ResourceBundle .

, , and . The PHP intl extension makes some ICU classes accessible in PHP, but it does not bundle the CLDR data. It uses the data installed globally on the system (which is independent of PHP).

bundle the CLDR data. It uses the data installed globally on the system (which is independent of PHP). The Symfony Icu component includes all the CLDR data, because Symfony needs access to the data in all locales, independent of the system's configuration. We even offered different versions: if you didn't have the intl extension installed, you'd have Icu 1.0.x , which ships the data as .php files. With the intl extension, you'd have 1.1.x or 1.2.x which ships the data as binary files, readable using the ResourceBundle class.

extension installed, you'd have Icu , which ships the data as files. With the extension, you'd have or which ships the data as binary files, readable using the class. The Symfony Intl component does two things: first, it provides access to the data of the Icu component ( Intl::get*Bundle()->get*() ). Second, it provides a partial PHP implementation for some ICU classes ( NumberFormatter ) which you can use when intl extension is not installed.

Understanding the problem¶ As you may know, Composer uses two files called composer.json and composer.lock to manage your project's dependencies. The composer.lock file stores the hashes of the package versions you have installed. The workflow that causes this problem is usually the following: Developer A , who has the intl extension, installs or updates Symfony.

, who has the extension, installs or updates Symfony. The composer.lock file will contain the Icu 1.2.x version.

file will contain the Icu version. Developer A commits the composer.lock file to the repository.

commits the file to the repository. Developer B , who doesn't have the intl extension, installs the project with the usual composer install command.

, who doesn't have the extension, installs the project with the usual command. Composer tries to install Icu 1.2.x , which requires intl , and the result is the infamous symfony/icu v1.2.x requires lib-icu >=4.4 error.

, which requires , and the result is the infamous symfony/icu v1.2.x requires lib-icu >=4.4 error. If Developer B executes composer update command, Composer will correctly detect that intl is not installed and it will use instead Icu 1.0.x .