web-dev-qa-db-ja.com

Apacheを再起動したりドメインを変更したりせずにphpのgettextキャッシュをクリアするにはどうすればよいですか?

これは phpマニュアル からの小さなコードスニペットです:

putenv('LC_ALL=zh_CN');
setlocale(LC_ALL, 'zh_CN');

bindtextdomain('domain', './locale');
textdomain('domain');

echo gettext('Hello');

domain.moファイルで定義されているように你好を出力しますが、問題はApacheが実行されている限り、gettext()は常に戻りますキャッシュされた結果。

domain.moHelloの翻訳を您好に変更すると、引き続き你好を出力します。

ただし、bindtextdomain()およびtextdomain()domain引数を新しい名前に変更することで、これを修正できます。 "domain"から"domain2"のように。しかし、これは.moファイルを更新するたびにphpファイルを編集するのは本当に面倒です。

いくつかのフォルダーを削除したり、いくつかのphp関数を呼び出してジョブを実行したりするなど、これを行うためのより良い方法はありますか?この目的のために小さなスクリプトを書くことができるように。

21
xiaoyi

すべての解決策( 12 、)は、キャッシュの問題を取り除くためにdomainを変更することを提案していますが、これはメモリ内に古いキャッシュを大量に作成します。

そこで、キャッシュ戦略の詳細についてgnu-gettextソースを掘り下げました(bindtextdom.c:78)。

bindtextdomain(domain, dirname)が呼び出されると、domainがキャッシュに存在するかどうかがチェックされます。その場合、dirnameがキャッシュ内のものと同じであるかどうかを確認します。これが失敗した場合、メモリ内に新しいドメインを作成する代わりに、同じドメインのキャッシュフラッシュを強制します。

修正は非常に簡単です。まず、_.mo_ファイルが保存されているlocaleフォルダーへのダミーリンクを作成します。

_cd locale
ln -s . nocache
_

次に、bindtextdomain()の前に1行追加します

_bindtextdomain('domain', './locale/nocache');
bindtextdomain('domain', './locale');
_

これで、キャッシュは毎回強制的にフラッシュされます。


更新:

このハックは場合によっては機能しない可能性があります(正確な条件を理解できません)。この解決策は[〜#〜] not [〜#〜]本番環境で使用する必要があるものですが、httpdを実行したまま何かを修正する必要がある場合に限ります。

可能な限り、最初からgettextを使用しないでください。これは本当に古いものであり、完全に非推奨にする必要があります。

15
xiaoyi

_messages.po_から_messages.mo_に変換した後、clearstatcache();関数を呼び出しましたが、Apacheを再起動しなくても正常に機能しました。それぞれの変更をロードすると、私が作成している言語ファイルが変更されます。

15
Praveen D

わかりました。私の場合、サービスphp5.6-fpm-sprestartを実行してphpfpmを再起動する必要がありました。

Php-fpmを使用している場合は、gettextのキャッシュをクリアするためにphpfpmを再起動する必要があります。Apache2の再起動は機能しません。

希望は他の誰かに役立つ。

5
chema

私にとっての解決策は、たとえば日付を使用して別の名前でファイルを保存し、ドメインを変更することでした。

#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);
1
pbs

使用する apachectl gracefulコマンドを使用して、構成を再読み取りするようにプロセスに要求します。リクエストの処理が終了すると、リクエストは終了します。だから安全に見えます。

Apache HTTP Server 2.2ドキュメント によると

USR1またはグレースフルシグナルにより、親プロセスは、現在の要求の後に終了するように(または、何も提供していない場合はすぐに終了するように)子にアドバイスします。親は構成ファイルを再度読み取り、ログファイルを再度開きます。各子が消滅すると、親はそれを新世代の構成の子に置き換え、新しい要求の処理をすぐに開始します。

それは私のために働いた。

0
Ben

私見にはそれを直接行う方法はありません(あなたが言及したドメインの回避策を除いて)、それが私たちが php-gettext を使用している理由です。

更新:これは motranslator として維持し始め、Composerでインストール可能で、すべてのPHPバージョンと互換性があります。

0
Michal Čihař