一元化された言語システムを使用した多言語アプリケーションに取り組んでいます。これは、各言語の言語ファイルと単純なヘルパー関数に基づいています。
en.php
$lang['access_denied'] = "Access denied.";
$lang['action-required'] = "You need to choose an action.";
...
return $lang;
language_helper.php
...
function __($line) {
return $lang[$line];
}
これまで、すべての文字列は現在のユーザーに宛てられたシステムメッセージでした。したがって、私は常にその方法でそれを行うことができました。次に、文字列が動的な値に依存する他のメッセージを作成する必要があります。たとえば、テンプレートファイルで、アクションポイントの数をエコーしたいと思います。ユーザーが1ポイントしかない場合は、「1ポイントあります。」とエコーする必要があります。ただし、0ポイントまたは1ポイントを超える場合は、「12ポイントあります」と表示されます。
置換の目的で(文字列と数値の両方)新しい関数を作成しました
function __s($line, $subs = array()) {
$text = $lang[$line];
while (count($subs) > 0) {
$text = preg_replace('/%s/', array_shift($subs), $text, 1);
}
return $text;
}
関数の呼び出しはのようになり__s('current_points', array($points))
ます。
$lang['current_points']
この場合は、で"You have %s point(s)."
、これはうまく機能します。
さらに一歩進んで、「(s)」の部分を取り除きたいと思います。そこで、さらに別の関数を作成しました
function __c($line, $subs = array()) {
$text = $lang[$line];
$text = (isset($sub[0] && $sub[0] == 1) ? $text[0] : $text[1];
while (count($subs) > 0) {
$text = preg_replace('/%d/', array_shift($subs), $text, 1);
}
return $text;
}
関数の呼び出しはまだのように見えます__s('current_points', array($points))
。
$lang['current_points']
今array("You have %d point.","You have %d points.")
です。
これら2つの機能をどのように組み合わせるのでしょうか。たとえば、ポイントと一緒にユーザー名を印刷したい場合(ランキングのように)。関数呼び出しは、のよう__x('current_points', array($username,$points))
に$lang['current_points']
なりarray("$s has %d point.","%s has %d points.")
ます。
採用しようとしましpreg_replace_callback()
たが、そのコールバック関数に代替値を渡すのに問題があります。
$text = preg_replace_callback('/%([sd])/',
create_function(
'$type',
'switch($type) {
case "s": return array_shift($subs); break;
case "d": return array_shift($subs); break;
}'),
$text);
どうやら、関数がwhileループを離れていないかのように「メモリ不足」エラーが発生しているため、$subsは定義されていません。
誰かが私を正しい方向に向けることができますか?この問題に取り組むには、おそらく完全に異なる(そしてより良い)方法があります。また、私はまだそれを次のように拡張したいと思います:
$lang['invite_party'] = "%u invited you to $g party.";
Adam invited you to his party."
男性と女性のためになるべき"Betty invited you to her party."
です。$subs
両方$u
に渡された値は$g
、ユーザーオブジェクトになります。