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
andResourceBundle
. - 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).
- 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 Icu1.0.x
, which ships the data as.php
files. With theintl
extension, you'd have1.1.x
or1.2.x
which ships the data as binary files, readable using theResourceBundle
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 whenintl
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. - The
composer.lock
file will contain the Icu1.2.x
version. - Developer A commits the
composer.lock
file to the repository. - Developer B, who doesn't have the
intl
extension, installs the project with the usualcomposer install
command. - Composer tries to install Icu
1.2.x
, which requiresintl
, 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 thatintl
is not installed and it will use instead Icu1.0.x
.
Understanding the solution
In order to solve this problem, the Intl component now includes all the CLDR data. As a consequence, the Icu component has been deprecated because is no longer needed.
Moreover, when you didn't have the intl
extension installed, previously you
could only access to the CLDR data in English. Now, you can access to all data
in all locales, independent of whether intl
is installed or not.
Given the large amount of information contained in the CLDR data, you may be worried by the impact in the total Symfony download size. Even if the data is stored as JSON files instead of using a binary format, the total compressed size is just about 2 MB.
Note Most of the contents of this post have been written by Bernhard Schussek, who kindly explained me all the pieces involved in the Symfony internationalization sub-framework.
To be precise, the next version of 2.3 and 2.5 won't have the ICU problem anymore, but 2.4 has this problem and it won't be fixed as it is unmaintained.
@Fabien, thanks for the correction. I've just updated the blog contents.
Awesome. Is it normal that the Intl README still says:
The replacement layer is limited to the locale "en". If you want to use other locales, you should install the intl extension instead.
?
RIP ICU
@Florian the CLDR data are available in all locales for things like
Intl::getCurrencyBundle()->getCurrencyNames($locale)
. but the stub implementations of PHP classes are still limited toen
the CLDR data may not be enough to stub them for all locale. Some stubs may be easy to make support all locales now that the CLDR data are here, but others (like the IntlDateFormatter) would be much more complexHi,
I've a project based on Symfony 2.5 that needs to run on CentOS 6 with PHP 5.5.
So I've got a following deps in composer
[..] "symfony/icu": "1.1.2"
IIUC after next release of Symfony 2.5 -> 2.5.6, I should remove symfony/icu dependency and it should work just fine on EL6?
Best regards, Michal
Good news overload towards SF2.6 these days... Thanks to all the contributors for the awesome work !
Thats good news. Certaintly this will improve the developer experience with symfony2. GJ!
@Michal: yes, exactly! :)
@Bernhard
Great. Thanks for fixing this!
Great work! When will the 2.5.6 tag be available?
It would be very grateful to have it as soon as possible :-) nice work!
What I have seen by updating my composer today: