Я читал о локалях в PHP, и кажется, что setlocale()
имеет проблемы с потоками. (Я не слишком хорошо знаком с потоками – в документах упоминается, что он не является потокобезопасным)
Я хотел бы дать моему проекту возможность иметь дело с определенными форматами чисел, а расширение Intl кажется интересным.
http://php.net/manual/en/book.intl.php
Должен ли я ожидать те же проблемы, что и setlocale()
использует расширение Intl?
Хорошо, мне тоже было любопытно, поэтому я придумал тест.
Сначала я тестировал setlocale()
с этими двумя файлами:
<?php # locale1.php error_reporting( E_ALL | E_STRICT ); date_default_timezone_set( 'Europe/Amsterdam' ); setlocale( LC_ALL, 'dutch_nld' ); // awkward Windows locale string sleep( 10 ); // let's sleep for a bit here echo strftime( '%A, %B %d, %Y %X %Z', time() );
а также
<?php # locale2.php error_reporting( E_ALL | E_STRICT ); date_default_timezone_set( 'America/Los_Angeles' ); setlocale( LC_ALL, 'english_usa' ); // awkward Windows locale string echo strftime( '%A, %B %d, %Y %X %Z', time() );
Затем я выполнил их на двух отдельных вкладках. Сначала locale1.php
, который спит в течение 10 секунд после установки локали, давая нам время для выполнения locale2.php
тем временем.
К моему удивлению, locale2.php
даже не позволяет правильно изменить локаль.Кажется, sleep( 10 )
в locale1.php
захватывает процесс Apache / PHP таким образом, что он не позволяет locale2.php
изменять локаль в то же время.Тем не менее, он тем не менее повторяет дату, но не локализован, как вы ожидали.
Редактировать: извините, сделайте это. Похоже, locale2.php
меняет локаль, а locale1.php
затем печатает английскую дату вместо голландца после сна. Таким образом, похоже, что это соответствует ожидаемому поведению от setlocale()
. /Редактировать
Затем я тестировал IntlDateFormatter
с этими двумя файлами:
<?php # locale1.php error_reporting( E_ALL | E_STRICT ); $dateFormatter = new IntlDateFormatter( 'nl_NL', IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'Europe/Amsterdam' ); sleep( 10 ); // let's sleep for a bit here echo $dateFormatter->format( time() );
а также
<?php # locale2.php error_reporting( E_ALL | E_STRICT ); $dateFormatter = new IntlDateFormatter( 'en_US', IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'America/Los_Angeles' ); echo $dateFormatter->format( time() );
а затем выполнить их снова на двух отдельных вкладках, так же как и с первым набором файлов. Это дает ожидаемые результаты: в то время как locale1.php
спящий locale2.php
красиво печатает дату на американо-английском языке в соответствии с американскими правилами, после чего locale1.php
красиво печатает дату на голландском языке по голландским правилам.
Итак, заключая, кажется, Intl
безопасен из этой проблемы setlocale
.
Но, разумеется, также ответ Хюнмина Кима . Я не мог прокомментировать это из-за отсутствия опыта использования Intl
. Я только недавно обнаружил Intl
.
Расширение Intl безопасно и очень полезно, если вы работаете, не работая внутри рамки.
Например, если вы используете Symfony2, ваши программы, скорее всего, сбой при использовании форм и валидаторов.