web-dev-qa-db-fra.com

Comment effacer le cache phette gettext sans redémarrer Apache pas changer de domaine?

Ceci est un petit extrait de code de php manual :

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

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

echo gettext('Hello');

Ce qui produiratel que défini dans le fichier domain.mo, mais le problème persiste tant qu'Apache est en cours d'exécution, gettext() renvoie toujours le résultat mis en cache.

Si je change la traduction de Hello endans domain.mo, le résultat sera toujours.

Cependant, il existe une solution à ce problème en modifiant l'argument domain de bindtextdomain() et textdomain() en un nouveau nom. Comme de "domain" à "domain2". Mais c’est vraiment pénible d’éditer le fichier php à chaque fois que j’ai mis à jour le fichier .mo.

Y a-t-il un meilleur moyen de le faire, comme supprimer des dossiers ou appeler des fonctions php pour faire le travail? Pour que je puisse écrire un petit script à cet effet.

20
xiaoyi

Chaque solution ( 1 , 2 , 3 ) suggère de changer la domain pour éliminer le problème de cache, mais cela créera de nombreuses obsolètes. cache en mémoire.

J'ai donc creusé dans la source gnu-gettext pour plus de détails sur la stratégie de cache (bindtextdom.c: 78.)

Lorsque bindtextdomain(domain, dirname) est appelé, il vérifie si domain existe dans le cache; Si tel est le cas, il vérifiera ensuite si dirname est identique à celui du cache. Si cela échoue, le vidage de la mémoire cache pour le même domaine sera forcé au lieu d'en créer une nouvelle en mémoire.

Le correctif est incroyablement simple. Commencez par créer un lien factice vers le dossier locale dans lequel votre fichier .mo est stocké:

cd locale
ln -s . nocache

Puis ajoutez une seule ligne avant bindtextdomain()

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

Maintenant, le cache est obligé de vider chaque fois.


Mises à jour:

Ce hack peut ne pas fonctionner dans certains cas (impossible de déterminer les conditions exactes.) Cette solution estPASquelque chose que vous devez utiliser dans un environnement de production, mais uniquement pour ceux qui ont besoin de réparer quelque chose tout en conservant httpd en cours d'exécution!

Chaque fois que vous le pouvez, évitez d’utiliser gettext dès le début, c’est vraiment quelque chose d’ancien et il devrait être déconseillé pour de bon.

13
xiaoyi

J'ai appelé la fonction clearstatcache(); après la traduction de messages.po en messages.mo et son fonctionnement fonctionne sans redémarrer Apache. Chargement de chaque changement que je fais dans n'importe quel fichier de langue.

14
Praveen D

ok, dans mon cas, je devais redémarrer phpfpm en faisant redémarrer le service php5.6-fpm-sp.

Si vous utilisez php-fpm, vous DEVEZ redémarrer phpfpm pour vider le cache de gettext, redémarrer Apache2 ne fonctionne pas.

L'espoir est utile à quelqu'un d'autre.

3
chema

La solution pour moi était de sauvegarder les fichiers sous un nom différent, en utilisant la date par exemple, puis en changeant le domaine:

#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

Utilisez la commande apachectl graceful pour demander au processus de relire la configuration. Il mettra fin à la demande APRÈS que la demande soit terminée. Donc ça a l'air sécuritaire.

Selon Documentation Apache HTTP Server 2.2

Le signal USR1 ou gracieux force le processus parent à conseiller aux enfants de quitter après la requête en cours (ou de quitter immédiatement s'ils ne servent rien). Le parent relit ses fichiers de configuration et rouvre ses fichiers journaux. Lorsque chaque enfant meurt, le parent le remplace par un enfant de la nouvelle génération de la configuration, qui commence à répondre immédiatement aux nouvelles demandes.

Cela a fonctionné pour moi.

0
Francis

À mon humble avis, il n’ya aucun moyen direct de le faire (à part la solution de contournement de domaine que vous avez mentionnée), c’est la raison pour laquelle nous utilisons php-gettext .

Mise à jour: que nous avons commencé à maintenir sous la forme motranslator , installable par Composer et compatible avec toutes les versions de PHP.

0
Michal Čihař