Это небольшой фрагмент кода из руководства php :
putenv('LC_ALL=zh_CN'); setlocale(LC_ALL, 'zh_CN'); bindtextdomain('domain', './locale'); textdomain('domain'); echo gettext('Hello');
Что будет выводить 你好, как определено в файле domain.mo
, но проблема в том, что Apache работает, gettext()
всегда возвращает результат кэширования.
Если я изменил перевод Hello на 您好 в domain.mo
, он все равно выведет 你好 .
Однако есть исправление для этого, изменив аргумент domain
bindtextdomain()
и textdomain()
на новое имя. Как от "domain"
до "domain2"
. Но мне очень больно редактировать файл php каждый раз, когда я обновляю файл .mo
.
Есть ли лучший способ сделать это, например, удалить некоторые папки или вызвать некоторые функции php для выполнения этой работы? Чтобы я мог написать небольшой скрипт для этой цели.
Каждое решение ( 1 , 2 , 3 ) предлагает изменить domain
чтобы избавиться от проблемы с кешем, но это создаст много устаревшего кеша в памяти.
Поэтому я вникнул в источник gnu-gettext для получения подробной информации о стратегии кэширования (bindtextdom.c: 78.)
Когда bindtextdomain(domain, dirname)
, он проверяет, существует ли domain
в кеше; если это так, тогда будет проверяться, совпадает ли имя dirname
в кеше. Если это не удастся, это заставит кеш-флеш для того же домена вместо создания нового в памяти.
Исправление невероятно просто, сначала создайте фиктивную ссылку на папку locale
где хранится ваш .mo
файл:
cd locale ln -s . nocache
Затем добавьте одну строку перед bindtextdomain()
bindtextdomain('domain', './locale/nocache'); bindtextdomain('domain', './locale');
Теперь кеш принудительно стирается каждый раз.
Обновления:
Этот хак может не работать в некоторых случаях (не удается определить точные условия.) Это решение НЕ является тем, что вы должны использовать в рабочей среде, но только для тех, кому нужно что-то исправить, сохраняя при этом httpd!
Всякий раз, когда вы можете, пожалуйста, избегайте использования gettext с самого начала, это действительно что-то древнее и должно быть устарело навсегда.
Я вызвал clearstatcache();
после перевода с messages.po
на messages.mo
и его работоспособности без перезапуска apache. Загружайте каждое изменение, которое я делаю в любом языковом файле.
нормально, в моем случае мне нужно было перезапустить phpfpm, выполнив перезагрузку службы php5.6-fpm-sp.
Если вы используете php-fpm, вы ДОЛЖНЫ перезапустить phpfpm, чтобы очистить кеш от Gettext, перезапуск apache2 не работает.
Надежда полезна кому-то другому.
Решение для меня состояло в том, чтобы сохранить файлы с другим именем, используя, например, дату, а затем изменить домен:
#the path for a domain, the .mo files must match the domain #the trick to avoid permanent caching, is to use different names for the domain, like the date messages_180320151250 $domain = 'messages_180320151300'; #sets the path for a domain, the .mo files must match the domain bindtextdomain($domain, $_SERVER['DOCUMENT_ROOT']."/apps/cp/locale"); textdomain($domain);
ИМХО нет прямого способа сделать это (помимо обходного пути, о котором вы говорили), это причина, почему мы используем php-gettext .
Обновление: Который мы начали поддерживать как motranslator , устанавливаемый Composer и совместимый со всеми версиями PHP.