PHP setlocale 没有效果

setlocale()函数没有设置所需的语言(德语)。


目标是输出月份名称。

这是我目前为止的测试代码:

<?php


date_default_timezone_set('Europe/Berlin');
setlocale(LC_ALL, 'de_DE.utf8');
// Or
setlocale(LC_ALL, 'de_DE@euro');
// Or
setlocale(LC_ALL, 'de_DE');
// Or
setlocale(LC_ALL, 'de');
// Or
setlocale(LC_ALL, 'ge');




echo strftime('%B');

产出:

阿朱

而不是

朱丽

有什么建议吗?

  • 我没有 ssh 或其他 shell 访问权限。
  • 该脚本在 Linux 服务器上运行。

PHP 版本5.6

106717 次浏览

是不是很有可能在你运行脚本的服务器上没有安装德国语言环境-你有服务器的 shell 访问权限吗? 那就试试

locale -a

查看安装了哪些语言环境

试试这个:

date_default_timezone_set('Europe/Berlin');
$loc=setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');
echo strftime('%B');

如果您没有对服务器的 shell 访问权限,这个解决方案可能会有所帮助。

如果您有 shell 访问权限,那么 Benjamin Seiller 的回答是最好的!

由于我没有其他可能性(shell) ,所以我使用 IntlDateFormatter 类找到了一个只使用 PHP 的解决方案。

<?php


// Example vars
$month = '6';
$year = '2014';


$fmt = new IntlDateFormatter('de_DE',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'Europe/Berlin',
IntlDateFormatter::GREGORIAN);


$lastMonth = mktime(0, 0, 0, $month -1, 1, $year);


$showLastMonth =  $fmt->format($lastMonth);
echo $showLastMonth;

你的代码是正确的。您可能只需要在运行脚本的服务器上安装正确的语言包。

在终端中,如果在运行命令 sudo locale -a之后没有列出要使用的语言,那么您必须通过运行以下命令来安装缺少的语言:

sudo /usr/share/locales/install-language-pack de_DE

(如果用户有 root 权限,则 sudo在这里是可选的)

然后,如果你仔细检查与 sudo locale -a你应该看到 de_DE.utf8

如果要安装法语软件包,请运行

sudo /usr/share/locales/install-language-pack fr_FR

然后您就可以像使用 setlocale(...)一样,在 PHP 中将您的语言设置为这些。


注: 如果您在一个非 utf8项目,您将需要从安装的包生成其他格式。 下面是如何在 ubuntu 上继续下去(这个工作也在 debian 上) :

编辑 < em >/var/lib/locales/support d.d/cs 并添加以下代码行

  fr_FR.iso88591 ISO-8859-1
fr_CA.iso88591 ISI-8859-1

然后逃跑

 sudo dpkg-reconfigure locales

然后再次运行 sudo locale -a,您应该会在列表中看到 Fr _ FR. iso88591Fr _ CA. iso88591,并且可以通过调用 setlocale(LC_ALL, 'fr_FR.iso88591');在 php 中使用它

取决于底层的操作系统 "de_DE"和其他可能错误的字符串。

在 Windows 下请参考以下列表:

通常是“ DEU”或者“ GERMAN”在 Win 下面。

已经提到了:

在 Linux 下,您可以使用 shell 命令查看所有地区:

locale -a

对于那些来这里寻找 date()不本地化的月份和工作日的名称:

= = 集中注意力 = =

Date ()只能返回英文的月/日名称,不能为您提供其他语言的翻译。

使用 strftime()代替!

感谢 Rico Neitzel 的提示。 不要尝试格式化 php 日期,而是使用 strftime。 查看用你的语言表示的月份名称的前3个字母(Ex。按照上面的 locale 安装说明,然后:

Date 命令: date (’d M Y’) //不可能从英文更改

setlocale( LC_ALL, "pt_BR"); // Portuguese, replace with your locale
echo strftime('%e %b %G');
result: "4 Dez 2016"


/**
* datelo funcion (date with locale)
* Credits: Sergio Abreu
* http://sites.sitesbr.net
* NOTE: Depend on availability of the locale in server.
*
*/


function datelo( $str, $locale='en_US', $time=null){


if( $time === null){  $time = time(); }


if ( preg_match("/[DlFM]/", $str)){


setlocale(LC_ALL, $locale);


$dict = array( 'd'=>'%d', 'D'=>'%a', 'j'=>'%e', 'l'=>'%A', 'N'=>'%u', 'w'=>'%w', 'F'=>'%B',
'm'=>'%m', 'M'=>'%b', 'Y'=>'%G', 'g'=>'%l', 'G'=>'%k', 'h'=>'%I', 'H'=>'%H', 'i'=>'%M',
's'=>'%S', 'S'=>'', 'z'=>'%j', 'n'=>'%m', ' '=>' ', '-'=>'-', '/'=>'/', ':'=>':', ','=>',');


$chars = preg_split("//", $str);
$nstr = '';


foreach ($chars as $c){
if ($c){ //skip empties
$nc = $dict[$c];
if( $c === 'n'){ // Fixes the extra zero
$nc = preg_replace("/^0+/", '', strftime( $nc));
}
elseif( $c === 'z'){ // Fixes the extra zero and decrease 1
$nc = preg_replace("/^0+/", '',  strftime( $nc)); // 023 turns 23
$nc = intval($nc) - 1;
}
$nstr .= $nc;
}
}
return strftime( $nstr);


}else{ // not localized
return date( $str, $time);
}
}

如果你使用的是 红帽机器,你可以运行:

localedef -v -c -i de_DE -f UTF-8 de_DE.UTF-8

然后重新启动 Apache 服务器

就我而言,这种做法行不通:

setlocale(LC_ALL, 'de_AT'); // false

而这确实有效:

Locale::setDefault('de_AT'); // true

这个确实管用:

setlocale(LC_ALL, 'de_AT.utf-8'); // true

现场程序输出:

$ locale -a
[...]
C.UTF-8
de_AT.utf-8
de_DE.utf-8
en_AG
[...]
apt-get install -y locales locales-all

太痛苦了。

我想把日期翻译成西班牙语,它在我的本地主机上工作,但不在服务器上(Ubuntu18)。结果发现我没有正确的本地化包。

首先,我检查了已安装的软件包,以确保它们不见了

locale -a

然后,我使用该脚本安装了西班牙语的 UTF

sudo pkg-reconfigure locales

然后我花了几个小时把头撞在桌子上,直到我意识到 你得重启 APACHE!

sudo service apache2 restart

我的故事到此结束,希望能有所帮助。

PHP 对不同版本的 setlocale()有着奇怪的支持。

下面的测试是在 Windows (同一台机器)、 Apache 2.4 x64(同一台 Web 服务器)、 PHP x64 TS (不同版本)上进行的。

setlocale() 报税表:

如果平台上没有实现区域设置功能,指定的区域设置不存在或类别名无效,则返回新的当前区域设置或 false

因此,我将在 PHP 7.0-8.1测试的不同版本上使用下面的测试。

var_dump(setlocale(LC_ALL, 'en_US'));

PHP 7.0,7.1返回 'en_US'
PHP 7.2 + (或更新)返回 false

var_dump(setlocale(LC_ALL, 'en-US'));

PHP 7.0 + 返回 'en-US'

以及用多个值进行测试,以确定哪一个值将被 setlocale()函数接受。
我使用这个数组。

$locale = ['en_US.UTF-8', 'en-US.UTF-8', 'en.UTF-8', 'en-US', 'en_US', 'en'];
var_dump(setlocale(LC_ALL, $locale));

PHP 7.0,7.1返回 'en_US.UTF-8'
PHP 7.2 + 返回 'en-US.UTF-8'

正如您所看到的,如果 PHP 在旧版本中支持 'en_US',并不意味着在新版本中也会支持。

对于 OP 的情况,可以尝试使用这个数组来查看哪个语言环境将被接受。

$locale = ['de_DE.UTF-8', 'de-DE.UTF-8', 'de.UTF-8', 'de_DE', 'de-DE', 'de', 'ge'];
var_dump(setlocale(LC_ALL, $locale));

在 Linux 或其他操作系统上,结果可能会有所不同。

我希望这对7.4有帮助

当我试图用西班牙语打印日期时,它给了我英文版本。

所以我在终端打印我所有的 lang 包:

# locale -a

它没有给我一个西班牙语,所以一个运行:

# sudo /usr/share/locales/install-language-pack es_ES

并在代码中将 te setlocale 更改为:

<?php
setlocale (LC_TIME, "es_ES", "es_ES.iso88591", "spanish");
?>

然后,使用以下命令重新启动 php 服务:

/etc/init.d/php7.4-fpm restart

就是这样