PHP 国际扩展线程是否安全


Is the PHP Intl extension thread safe?

我一直在阅读有关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,则在使用表单和验证器时,您的程序很可能会崩溃。