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');

Выход:

июнь

вместо

Juni

Какие-либо предложения?

  • У меня нет доступа по ssh или другой оболочке.
  • Скрипт работает на сервере Linux.

PHP версия 5.6

14 ответов

Решение

Это решение может помочь, если у вас нет доступа к серверу.

Если у вас есть доступ к оболочке, то ответ Бенджамина Сейллера самый лучший!

Поскольку у меня нет никаких других возможностей (оболочка), я нашел решение с использованием только PHP с использованием класса IntlDateFormatter.

<?php

// Example vars
$month = '6'; // 1-12
$year = '2014'; // four digit year

$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;

Вполне вероятно, что немецкий язык не установлен на сервере, на котором вы запускаете сценарий - есть ли у вас доступ к серверу? Тогда попробуй

locale -a

чтобы увидеть, какие локали установлены. Также посмотрите здесь. Можно ли полагаться на setlocale и полагаться на устанавливаемые локали?

Для тех, кто приезжает сюда, ищет date(), но не локализует названия месяца и дня недели:

== Обратите внимание ==

Функция date() может возвращать названия месяцев / дней только на английском языке и не может переводить переводы на другие языки.

Ваш код правильный. Возможно, вам просто нужно установить правильный языковой пакет на сервере, на котором вы запускаете скрипт.

В терминале, если нужный язык не указан при запуске команды sudo locale -aтогда вам нужно будет установить его, выполнив следующую команду:

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

(sudo здесь необязательно, если у вашего пользователя есть права root)

Тогда, если вы дважды проверьте с sudo locale -a Тебе следует увидеть de_DE.utf8,

Если вы хотите установить пакет на французском языке, запустите

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

Тогда вам будет разрешено установить свой язык на них в PHP с помощью setlocale(...) Точно так же, как ты это сделал.


Примечание. Если вы работаете не в UTF8-проекте, вам необходимо сгенерировать другие форматы из установленных пакетов. Вот как продолжить работу с Ubuntu (эта работа также работает и с Debian):

отредактируйте /var/lib/locales/supported.d/cs и добавьте следующие строки

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

и беги

 sudo dpkg-reconfigure locales

Затем снова запустив sudo locale -a вы должны увидеть оба fr_FR.iso88591 и fr_CA.iso88591 в списке, и вы можете использовать его в php, вызвав setlocale(LC_ALL, 'fr_FR.iso88591');

Попробуй это:

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

Это была такая боль.

Я хотел перевести даты на испанский, и он работал на моем локальном хосте, но не на сервере (Ubuntu 18). Оказалось, что у меня нет нужных пакетов локали.

Сначала я проверил установленные пакеты, чтобы убедиться, что они отсутствуют.

locale -a

Затем я установил испанский UTF, используя скрипт

sudo pkg-reconfigure locales

А потом я часами бился головой о стол, пока не понял, что ВАМ НУЖНО ПЕРЕЗАПУСКАТЬ APACHE!

sudo service apache2 restart

И это конец моей истории. Надеюсь, это поможет.

В моем случае это не работает:

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
[...]

Страница руководства PHP для 'setlocale' говорит:

Примечание. Возвращаемое значение setlocale() зависит от системы, в которой работает PHP. Он возвращает именно то, что возвращает системная функция setlocale.

Если у вас есть root-доступ (debian), вот решение:

редактировать

/etc/locale.gen

Вы можете добавить / удалить, какие локали вам нужно использовать. После сохранения файла запустите:

locale-gen

и ты должен быть в порядке. На моем сервере мне пришлось перезапустить Apache, чтобы увидеть изменения.

apt-get install -y locales locales-all

В зависимости от базовой ОС "de_DE" и другие, возможно, неправильная строка.

Под Windows ссылаются на эти списки:

Обычно это "DEU" или "НЕМЕЦКИЙ" под Win.

Уже упоминалось:

Под Linux вы можете увидеть все локали с помощью команды shell:

locale -a

PHP имеет странную поддержку в разных версиях.

Ниже приведены тесты для Windows (та же машина), Apache 2.4 x64 (тот же веб-сервер), PHP x64 TS (разные версии).

Возвращаться:

Возвращает новую текущую локаль или, если функциональность локали не реализована на вашей платформе, указанная локаль не существует или имя категории недопустимо.

Итак, я буду использовать приведенные ниже тесты на разных версиях PHP. Протестировано на PHP 7.0 - 8.1.

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

PHP 7.0, 7.1 возвращают .
Возврат 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 или другой ОС.

Спасибо Рико Нейцель за подсказку. Вместо того, чтобы пытаться форматировать дату php, используйте strftime. Чтобы увидеть первые 3 буквы названия месяца на вашем языке (например, Dez вместо Dec от Dezembro, а не декабря), следуйте приведенным выше инструкциям по установке локали, а затем:

команда 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);
 } 
}

Если вы используете Red Hat, вы можете запустить:

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

Затем перезагрузите сервер Apache

Я надеюсь, что это поможет php 7.4

Когда я попытался напечатать дату на испанском языке, она выдала мне английскую версию.

Итак, я печатаю в терминале все свои языковые пакеты:

      # 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

вот и все

Другие вопросы по тегам