2014. 7. 1. 10:41

다국어 지원용 gettext 캐시 클리어 방법

다국어 지원을 하기 위해서 시스템상의 번역파일(.po, .mo)을 이용하기 위해 

bindtextdomain 과 gettext 또는 _T() 를 사용하다 보면 .mo 파일이 업데이트된 이후에도 캐쉬에서 데이타를 읽어들여서 변경된 내용이 적용되지 않는다. 이 경우에는 php를 재시작 해줘야 하는데 재시작 없이 처리하는 방법을 알아보자.



방법 1. 번역파일이 존재하는 디렉토리에 소프트링크를 추가하여 bindtextdomain 으로 추가한다.

출처 : http://stackoverflow.com/questions/13625659/how-to-clear-phps-gettext-cache-without-restart-apache-nor-change-domain

cd locale
ln -s . nocache


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


- 주의 : 이 방법은 환경에 따라 원하는 동작이 되지 않는 경우도 있으므로 충분히 테스트를 하고 적용해야 한다.


방법 2. mo파일을 시간별로 미리 여러개를 만들어서 매번 다른걸 로드해서 캐싱되지 못하게 하는 방법.

출처 : http://www.php.net/manual/en/function.gettext.php#58310

<?php
function initialize_i18n($locale) {
    
putenv('LANG='.$locale);
    
setlocale(LC_ALL,"");
    
setlocale(LC_MESSAGES,$locale);
    
setlocale(LC_CTYPE,$locale);
    
$domains glob($locales_root.'/'.$locale.'/LC_MESSAGES/messages-*.mo');
    
$current basename($domains[0],'.mo');
    
$timestamp preg_replace('{messages-}i','',$current);
    
bindtextdomain($current,$locales_root);
    
textdomain($current);
    }
?>

msgfmt messages.po -o messages-`date +%s`.mo


- 주의 : 먼가 비효율적인 방법임


방법 3. 로드될때 마다 하나의 mo 파일을 다른 이름으로 복사해서 복사한 파일을 로드하는 방법

출처 : http://blog.ghost3k.net/articles/php/11/gettext-caching-in-php


// settings you may want to change
$locale = "en_US";  // the locale you want
$locales_root = "locales";  // locales directory
$domain = "default"; // the domain you're using, this is the .PO/.MO file name without the extension

// activate the locale setting
setlocale(LC_ALL, $locale);
setlocale(LC_TIME, $locale);
putenv("LANG=$locale");
// path to the .MO file that we should monitor
$filename = "$locales_root/$locale/LC_MESSAGES/$domain.mo";
$mtime = filemtime($filename); // check its modification time
// our new unique .MO file
$filename_new = "$locales_root/$locale/LC_MESSAGES/{$domain}_{$mtime}.mo"; 

if (!file_exists($filename_new)) {  // check if we have created it before
      // if not, create it now, by copying the original
      copy($filename,$filename_new);
}
// compute the new domain name
$domain_new = "{$domain}_{$mtime}";
// bind it
bindtextdomain($domain_new,$locales_root);
// then activate it
textdomain($domain_new);
// all done