4

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

我想让我的项目能够处理某些数字格式,并且 Intl 扩展似乎很有趣。

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

setlocale()我应该期待与使用 Intl 扩展相同的问题吗?

4

2 回答 2

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 )在劫持 Apache/PHP 进程中。当然,它确实同时呼应了日期,只是没有像您期望的那样本地化。locale1.phplocale2.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() );

然后在两个单独的选项卡中再次执行它们,与第一组文件的方式相同。这确实给出了预期的结果:while locale1.phpis sleeplocale2.php很好地根据美国规则以美式英语打印日期,之后locale1.php根据荷兰规则很好地用荷兰语打印日期。

因此,总而言之,似乎Intl可以避免这个setlocale问题。

但当然也要注意金贤敏的回答。由于缺乏使用经验,我无法对此发表评论Intl。我最近才发现Intl

于 2012-06-14T01:42:52.640 回答
2

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

例如,如果你使用 Symfony2,你的程序在使用 Forms 和 Validators 时很可能会崩溃。

于 2012-06-14T01:03:40.890 回答