ローカライズ

PHPにてローカライズを行うには、メッセージにIDを振り言語定数等で切り替えるか、
define関数を使用して、文字列を定数化して定義しているファイルのrequireを切り替えるかの方法がある。

defineは、速度的には高速に処理が出来る。define自体がPHPなのでファイルを解析したり剃る必要がない分早い
が、変更等があった場合にメンテナンスが面倒になる。

ある一定のフォーマットのCSVファイルを読込方式は、CSVフォーマット解析に時間が掛かるが、CSVなのでメンテナンスが容易である。

今回はメンテナンス等をしやすいようにCSVを読み込む方式で実装を行なった。
XMLやJSON等の選択肢もあったが、有効な編集ツールが見つからなかったため採用しなかった。

<?php
/**
* 多言語対応クラス
* UTF-8形式で保存されたCSVファイルを読込、
* getのargsに引数があれば置換処理を行いテキストを取得する
*/
class LanguageCommon{
protected $lang;
protected $lang_file;
protected $localize;

public function __construct( $lang ){
$this->LanguageCommon( $lang );
}

public function LanguageCommon( $lang ){
$this->lang = $lang;
$this->lang_file = strtolower($lang).’.csv’;
$this->localize = $this->load_csv( $this->lang_file );
}

/**
* 文言を取得する
* argsの配列のキーを置換文字として配列の値に置換する
* argsは多重配列には対応していない
*/
public function get( $msg_id, $args = null ){
$message = “”;
if( !isset($this->localize[ $msg_id ] ) ) return $message;
$message = $this->localize[ $msg_id ];
if( count( $args ) ){
$keys = array_keys( $args );
foreach( $keys as $key ){
$message = str_replace( “{“.$key.”}”, $args[$key], $message );
}
}

return $message;
}

/**
* ローカライズの準備が出来ているかどうか
*/
public function isReady(){
if( $this->localize ) return true;
return false;
}

/**
* ローカライズの読込準備を行う
*/
public function ready(){
$this->lang_file = PRIVATE_DIR.’applib/lang/’.$lang.’.csv’;
$this->localize = $this->load_csv( $this->lang_file );
return $this->isReady();
}

/**
*
*/
protected function load_csv( $filename ){
if( !file_exists( $filename ) ) return null;
$fp = fopen( $filename, “r” );
if( !$fp ) return null;

$ret = array();
while( ($line = fgetcsv( $fp, 1000, “\t”)) !== FALSE ){
if( count( $line ) == 0 ) continue;

$idx = trim($line[0]);
$val = ”;
if( isset($line[1] ) ) $val = trim($line[1]);

if( substr( $idx, 0, 1 ) == ‘#’ ) continue;
if( $idx == “” ) continue;

$ret[ $idx ] = $val;
}

fclose( $fp );

return $ret;
}
}
?>

言語定義ファイルは…

# コメント行
#空行もスキップする
msg_001, hogehoge
msg_002, “hagehoge”
msg_003,”{key}←getの引数が有れば置換される”