4

多言語対応が必要な PHP Web サイトを開発しています。このため、次のヘッダーを持つ翻訳関数を実装しました。

function t($string, $replace_pairs = array(), $language = NULL)

基本的に、この関数は私のプロジェクトの複数のファイルで次のように呼び出されます。

echo '<p>' . t('Hello world!') . '</p>';
$hello_String = t("Hello @name!", array('@name'=>$username));

翻訳文字列をまだ生成していません。複数の翻訳ファイルを自動的に (言語ごとに 1 つ) 生成したいと考えています。

私が探しているのは、この t() 関数へのすべての呼び出しを検索し、次の構造を持つ php ファイルを生成する bash プログラム (または、たとえば grep を使用する単一のコマンド) です。

<?php
/* Translation file "fr.php" */
$strings['fr']['Hello world!'] = '';
$strings['fr']['Hello @name!'] = '';

誰かがこの状況に遭遇したことがあり、これで私を助けることができますか?

どうもありがとうございました。

敬具、

マチュー

4

6 に答える 6

11

はい、あなたはこれに最初に遭遇したわけではありません。:)

これには由緒ある gettext システムを使用できます。独自の関数を発明する必要はありません。次に、関数xgettextを使用して文字列を抽出するコマンド ライン ユーティリティである を使用します。_()

なんらかの理由で独自のシステムをロールバックする場合token_get_allは、ソースをトークン化するために使用する PHP スクリプトを作成し、トークンを調べT_FUNCTIONて、値が の s を探すのが最善の策ですt

于 2012-08-13T16:03:01.430 に答える
2

このスクリプトを試してくださいhttp://pastie.org/4568713

使用法:

php script.php ./proj-directory lang1 lang2 lang3

これによりlang1.php、ディレクトリlang2.phpに、、lang3.phpファイルが作成されます./lang

于 2012-08-22T15:32:20.537 に答える
2

車輪を再発明する必要はありません

Drupal はローカリゼーションに同じ t() 関数を使用しており、potxモジュールはあなたの味方です。

drupal インスタンスをまだ持っていない場合、またはインストールしたい場合は、potx.incファイルを見て、スクリプトで再利用できます。

翻訳テンプレート エクストラクタの完全なAPI ドキュメントは次のとおりです。

于 2012-08-24T01:27:09.157 に答える
0

必要なのは(非常に単純な)「テンプレートシステム」ですが、問題にはテンプレートの2つのインスタンスがあります。

  1. $X を設定して、Hello $X!" " を " Hello Jonh!" または " " に変換します。Hello Maria!(PHP は文字列宣言でこれを行います)。
  2. 適切なテンプレートを選択します:Hello $X!英語の場合は " ¡Hola $X!"、スペイン語の場合は " "。

項目 1 はより単純ですが、アルゴリズムの順序は 2,1 (項目 2 と項目 1) です。この単純なタスクでは、正規表現は必要ありません (PHP の「プレースホルダー付き文字列」を再発明するため)。

説明する

項目 1 の場合、最も簡単な方法は、"Hello" と言う特殊な関数を宣言することです。

// for any PHP version.
function template1($name) { return "<p>Hello $name!</p>";}
print template1("Maria");  

項目 2 については、一般化が必要です。これは、PHP がクロージャーによって行うことでもあります。

header('Content-Type: text/html; charset=utf-8'); // only for remember UTF8.
// for PHP 5.3+. Use 
function generalTemplate1($K) {
    // $K was a literal constant, now is a customized content.
    return function($name) use ($K) {return "<p>$K $name!</p>"; };
}
// Configuring template1 (T1) for each language: 
$T1_en = generalTemplate1('Hello'); // english template
$T1_es = generalTemplate1('¡Hola'); // spanish template 
// using the T1 multilingual
print $T1_en('Jonh');  // Hello Jonh!
print $T1_es('Maria'); // ¡Hola Maria!

その他のテンプレートについては、generalTemplate2()、generalTemplate3() などを使用してください。$T2_en$T2_es$T2_fr$T3_en$T3_esなど

解決

さて、実際に使用するために、配列を使用するのが好きです...まあ、データ構造の問題と、さらに1レベルの一般化があります。コストは、プレースホルダーの変数名パーサーです。preg_replace_callback() で単純な正規表現を使用しました。

function expandMultilangTemplate($T,$K,$lang,$X) {
// string $T is a template, a HTML structure with $K and $X placeholders. 
// array  $K is a specific language constants for the template.
// array  $lang is the language, a standard 2-letter code. "en", "fr", etc.
// array  $X is a set of name-value (compatible with $T placeholders).
// Parsing steps:
$T = str_replace('{#K}',$K[$lang],$T);  // STEP-1: expand K into T with lang.
// STEP-2: expand X into T 
global $_expMultTpl_X;  // need to be global for old PHP versions
$_expMultTpl_X = $X;   
$T = preg_replace_callback(
        '/@([a-z]+)/',
        create_function(
                '$m',
                'global $_expMultTpl_X; 
                 return array_key_exists($m[1],$_expMultTpl_X)? 
                     $_expMultTpl_X[$m[1]]: 
                     "";
                 '
        ),
        $T
    );
    return $T;
}
// CONFIGURING YOUR TEMPLATE AND LANGUAGES:
$T = "<p>{#K} @name@surname!</p>";
$K = array('en'=>'Hello','es'=>'¡Hola');
// take care with things like "!", that is generic, and "¡" that is not.

// USING! 
print expandMultilangTemplate(
        $T, $K, 'en', array('name'=>'Jonh', 'surname'=>' Smith')    );
print expandMultilangTemplate($T, $K, 'es', array('name'=>'Maria'));

このスクリプトは PHP5 でテストしましたが、古いバージョン (PHP 4.0.7 以降) で動作します。

「多言語ファイル」について: 翻訳がファイルに含まれている場合は、次のようなものを使用できます

$K = getTranslation('translationFile.txt');
function getTranslation($file,$sep='|') {
  $K = array();
  foreach (file($file) as $line) {
      list($lang,$words) = explode($sep,$line);
      $K[$lang]=$words;
  }
}

そしてファイル

en|Hello 
es|¡Hola

PHP 5.3 で最もシンプル

PHP 5.3+ を使用している場合、この「最も単純な多言語テンプレート システム」を表現するシンプルでエレガントな方法があります。

function expandMultilangTemplate($T,$K,$lang,$X) {
    $T = str_replace('{#K}',$K[$lang],$T);
    $T = preg_replace_callback(
            '/@([a-z]+)/',
            function($m,$X=NULL) use ($X) {
                    return array_key_exists($m[1],$X)? $X[$m[1]]: '';
            },
            $T
     );
     return $T;
}
于 2012-08-24T22:04:45.270 に答える
0

Yii フレームワークも同じ機能を使用しています。MessageCommand クラスを参照して ください https://github.com/yiisoft/yii/blob/master/framework/cli/commands/MessageCommand.php#L125

于 2012-08-24T20:04:32.743 に答える
0

次の 2 つの関数が必要です。

1- PHP ファイルのディレクトリをスキャンします。このように

2- t 関数、grep 文字列を照合し、言語ファイルを生成します。お気に入り

  function genLang($file) {
    $content = file_get_contents($file);
    preg_match(...);
    foreach(...){
        echo(...);
    }
  }
于 2012-08-23T21:12:42.363 に答える