2012-06-14 103 views
4

我一直在阅读关于PHP中的语言环境,似乎setlocale()有线程问题。 (我不是太熟悉线程 - 该文档提到它不是线程安全的)PHP Intl扩展线程安全吗?

我想给我的项目来处理某些数字格式和国际扩展似乎有趣的能力。

http://php.net/manual/en/book.intl.php

我能有相同的问题,setlocale()已经使用国际扩展?

回答

3

好吧,我很好奇这个自己一样,所以我设计了一个试验。

首先我测试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问题安全。

但是也记住Hyunmin Kim's答案当然。由于缺乏使用Intl的经验,我无法对此发表评论。我最近才发现Intl

+0

有趣的测试 - 我还没有尝试区域设置,所以这是我的新领域。 'setlocale'和'Intl'方法有什么区别? – RS7

+0

嗯,一方面,'Intl'似乎更安全,因此在这方面更可靠。你提到的'setlocale'的线程问题正是我演示的这个问题:你不能确定另一个线程(意味着另一个php脚本)在你打印一个很好的本地化日期时不会改变语言环境(或其他任何依赖于'setlocale')的属性。 –

2

如果您不在框架内工作,Intl扩展是安全且非常有用的。

举例来说,如果你是,你的程序将使用表单和验证时,最有可能崩溃使用Symfony2的。

+0

我的项目目前正在使用CodeIgniter框架 - 你知道任何问题吗? – RS7