Используйте PHP Gettext без необходимости устанавливать локали
Я искал варианты интернационализации проекта с открытым исходным кодом:
Gettext, который, кажется, все рекомендуют, очевидно, нуждается в локалях, которые должны быть "установлены в вашей системе", чтобы быть использованными. Смотрите это примечание в руководстве по PHP, которое отражает мою ситуацию. Этот ТАК вопрос также спрашивает о той же проблеме. Это не подходит для проекта с открытым исходным кодом, потому что я не могу поверить, что у конечных пользователей установлены соответствующие локали в их системе. Кроме того, очень странно, что вам нужно устанавливать локали только для того, чтобы использовать переведенные строки (IMO).
Zend_Translate также иногда рекомендуется в пользу gettext, но я не использую Zend Framework, поэтому я не думаю, что это вариант для меня. Некоторые люди говорят, что вы можете отделить его от Zend Framework, но я понятия не имею, как. Если кто-нибудь скажет мне, какие файлы мне нужны (я скачал архив Zend Framework), чтобы выбрать их, я был бы открыт для использования Zend_Translate.
Массивы. Это то, что я делаю сейчас, но это не идеально, потому что:
- Он будет использовать много памяти для определения каждого перевода, когда большая часть не будет использоваться текущей страницей.
- У меня возникают проблемы с дублированием ключей в массиве, который уже стал длиной в 1000 строк кода, и я еще ничего не добавил...
- Это означает, что непрограммисты действительно не могут переводить, тогда как POedit - это стандарт, который все ожидают использовать.
Могу ли я как-то прочитать .mo
файлы без Gettext или Zend_Translate, или я должен использовать Gettext? Если так, как я могу заставить все локали работать, как в вопросе, с которым я связан выше?
РЕДАКТИРОВАТЬ: Теперь я хочу использовать Zend_Translate. Мне просто нужно выяснить, какие файлы мне нужны (было бы здорово, если бы их можно было объединить в один файл) - мне не нужен весь Zend Framework в моем проекте.
Обновление: мне было интересно посмотреть, как большие проекты с открытым исходным кодом обрабатывают i18n:
- Moodle использует массивы.
- Drupal, похоже, использует массивы с резервной базой данных. Они также бегут
setlocale('C')
чтобы получить общий язык и обойти весьsetlocale
беспорядок. - Wordpress использует кучу своих собственных функций для i18n, хотя ниже использует gettext.
Так что, насколько я вижу, ни один из этих трех случайных проектов не использует Zend_Translate или gettext напрямую.
Может быть, это хорошая идея, чтобы использовать C
locale, сохраните название языка в текстовом доменном имени и перейдите оттуда.
Так вот, насколько я имею с этим:
$lang = 'de'; //debug
setlocale( LC_ALL, 'C' );
bindtextdomain( 'default', PATH . "/locale/$lang" );
bind_textdomain_codeset( 'default', 'UTF-8' );
textdomain( 'default' );
var_dump( file_exists( PATH . "/locale/$lang/C/LC_MESSAGES/default.mo" ) ); //bool(true)
Но я все еще получаю английскую строку, хотя я использовал poedit, msgfmt и т. Д. Для создания соответствующих файлов. Я также попытался перезапустить Apache.
3 ответа
Вот решение:
$lang = 'de'; //debug
setlocale( LC_ALL, 'C.UTF-8' );
bindtextdomain( 'default', PATH . "/locale/$lang" );
bind_textdomain_codeset( 'default', 'UTF-8' );
textdomain( 'default' );
Единственная разница между этим и примером, который я разместил внизу моего ответа, состоит в том, что он использует C.UTF-8
не просто C
,
Я буду больше тестировать это, и если это работает кроссплатформенно, и обновлю этот ответ, если я узнаю что-нибудь еще.
Попробуйте gettext-php. Это вставная замена для gettext, написанного на PHP. Я думаю, что изначально это было сделано для WordPress, потому что WP должен работать на общих хостах, которые не всегда настраиваются для каждой локали. Мне кажется, это тоже ваша проблема.
Это немного повлияло на производительность, но для меня это не было проблемой.
Для тех, у кого все еще есть проблемы с этим, вы можете попробовать код ниже, который я получаю отсюда: http://php.net/manual/en/function.gettext.php
Это решило меня на сервере freebsd, без дополнительной установки локали (fr_FR и my_MY). Этот код также полезен, когда у вас есть проблемы с кешем gettext.
<?php
function initialize_i18n($locale) {
$locales_root="/app/php/locale"; // change This to where you locale folder at
putenv('LANG='.$locale);
setlocale(LC_ALL,"");
setlocale(LC_MESSAGES,$locale);
setlocale(LC_CTYPE,$locale);
$domains = glob($locales_root.'/'.$locale.'/LC_MESSAGES/*.mo');
$current = basename($domains[0],'.mo');
$timestamp = preg_replace('{messages-}i','',$current);
bindtextdomain($current,$locales_root);
textdomain($current);
}
?>