1

翻訳モジュール

序章

私のコードはこれまでのところ機能していますが、これが私が望むものを実装する適切な方法であるかどうかはわかりません。Web ページの文字列を翻訳する小さな関数があります。番号で呼び出すと、1 つのテーブルで ID が検索され、そのページを対象としている場合にのみ表示されます。文字列で呼び出すと、別のテーブルで文字列が検索され、文字列が存在しない場合、関数は渡された文字列を出力し、「_」をスペースに置き換えて警告します。

正しく実装されているかどうか知りたいことが 2 つあります (前述のとおり、動作しますが、良いアイデアかどうかはわかりません)。しかし、最初のコード。

コード

// Function to output language strings.
function text($Id)
    {
    // Already defined and tested that are valid (sql injection avoided also)
    global $Lang;
    global $FullUrl;

    if (is_int($Id))    // If a number is being passed
        {
        $results = mysql_query("SELECT * FROM translations WHERE id='$Id' AND page='$FullUrl'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang])) echo $row[$Lang];  // If there is some, echo it
        else error($FullUrl,$Lang); // Else, calls error function
        }

    else    // If a string is being passed
        {
        $results = mysql_query("SELECT * FROM htranslations WHERE keyword='$Id'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang])) echo $row[$Lang];  // If it exists in the table, echo it
        else    // Else (it doesn't exist)
            {
            $NewId = str_replace("_", " ", $Id);    // Replace the "_" with " "
            echo "<span style='color: red;' title='";   // Set a red color (warning)
            text(Wrong_sentence);   // Call this function and echo "This sentence could be wrong"
            echo "'>".$NewId."</span>"; // Echo the passed string with spaces
            error($FullUrl,$Lang,$Id);
            }
        }
    }

1. echo は関数の内側と外側のどちらが良いですか?

私はすでにこの質問を読んでおり、文字列をさらに操作するつもりはありません。したがって、その投稿から、最善のアイデアは、私がすでに行ったように、関数内でエコーすることだと推測していますが、まだ確信が持てないので、この特定のケースについてあなたの意見を知りたいです. 値を返してその値をエコーするか、関数からエコーする方がよいでしょうか? なんで?私の質問は、パフォーマンスとコードを使いやすくすることに焦点を当てています。

2. この関数を関数内から呼び出すのは危険ですか?

ご覧のとおり、私が書いた最後の行の 1 つでtext(Wrong_sentence);. 別の関数から関数を呼び出すことができることは知っていますが、同じ関数から関数を呼び出すことはできますか? Wrong_sentenceたとえば、 table キーワードが削除または変更された場合など、自分自身を呼び出す無限ループに入るのではないかと心配しています。また、そこにある可能性のある他のセキュリティへの影響についても認識していません。

コードに関する他の種類のフィードバックは大歓迎です!!

4

2 に答える 2

3

懸念事項の分離は、最初に取り組むべき部分です。それはまさに不可欠です。

一般に、作成したのは、これに意味のあるグローバル関数です。少なくともビューで利用できるはずです。私はいくつかの懸念がありますが:

  1. グローバル: グローバル変数を使用しますが、それが気に入らないだけです。さらに悪いことに、そこに何が入っているかさえチェックしません。最終的にそれらを使用する場合は、使用する前に必ず確認してください。たとえば、上書きされたり、あいまいなエラーが発生したりする可能性があります。

  2. 関心の分離: この関数は、モデルにテキストを要求するだけです。それでおしまい。そのモデルは、false/void/error またはテキストのみを返す可能性があります。対処する

  3. この関数の場所: 一般に、これは MVC 用語でヘルパーと呼ばれるので、ヘルパーを見てみると面白いかもしれません。たとえば、CakePHP では次のようになります: http://book.cakephp.org/2.0/en/views/helpers.html開発者。ヘルパーを見つけたら、それを探す場所を知っていれば、システムの任意の場所でグローバル関数を定義できます。

  4. エコーしない: エコーは良くありません。必要なときにのみビューに直接配置することを好みます。なんで?結果のデバッグが容易になり、変数とエコーでそれらを使用するための1つのアプローチしか必要ないためです。

    エコー テキスト (123);

それ以上のコードなどは必要ありませんが、標準を生成します。たとえば、変数または他のメソッドで必要な場合:

echo strtotupper(text(123));

同じことが必要なテストを行っている場合は、関数からの応答が必要です。エコーをテストすることは明らかに可能ですが、リターンの方がはるかにうまく機能します。

  1. URL とテキストの組み合わせ: テキストの一部は他のコンテンツに属します。URL はそのコンテンツにリンクしていますが、正しいリンクではないようです。たとえば、タイトルの URL にタイプミスがあるページを考えてみましょう。URL は修正されましたが、テキストはもうリンクされていません。

  2. 1 つの機能に 2 つの機能を組み合わせる: コードの単体テストを開始すると、これがより複雑な問題を引き起こす理由に気付くでしょう。getTextById と getTextByKeyword の 2 つの関数があります。基本的に、問題はすでにここにあります。

    "SELECT * FROM htranslations WHERE キーワード ='$Id'"

キーワードと思われる $Id を検索しています。エラーが発生しやすいコード。フレーバーを選んで、それに固執します。通常、ハードコードされた ID は何も言わないので嫌いです。したがって、次のようなものを使用することをお勧めします。

text('CONTACT_ADDRESS')

その種のタグは読み取り可能です (これはビューで重要であり、理にかなっています。たとえば、悪いもの:

<p><?php text(24234); ?></p>
<p><?php text(96985); ?></p>

あなたはそれが何であるか見当もつかない. しかし、これをビューに記述した場合、完全に明確になります。

<p><?php text('ORGANISATION_INTRODUCTION'); ?></p>
<p><?php text('ORGANISATION_FOUNDERS'); ?></p>

これらは 2 つのテキストですが、どれがどれかわかりました。また、ページ自体を見れば、それらを見つけることができる場所もわかります。ご覧のとおり、これらの単純な例ではページ プレフィックスを使用していますが、明らかにグローバル テキストも存在する可能性があります。サイドバーのテキストのように。ニーズに応じて、ここには多くのオプションがあります。ページ名を自動的に追加することもできます。

  1. MySQL 関数の悪用: もうこれを行わないでください:

    $results = mysql_query("SELECT * FROM htranslations WHERE keyword='$Id'") or die ('Could not query:' . mysql_error());

PDO ステートメントまたはその他の安全なものを作成し、エラーをキャッチしたり、入力を検証したりするだけです。この種の問題が原因で、非常に多くのハッキングが見られます。

  1. すでに利用可能な解決策: テキストを翻訳するのはあなたが初めてではありません。ですから、多言語をサポートするフレームワークやhttp://www.gnu.org/software/gettext/など、すでに利用可能なシステムを例に見てみませんか。すでにたくさんのトリックがあるのに、なぜ新しいトリックを開発する必要があるのでしょうか?

  2. 再帰的: 現在、見つからないというエラーのために間違ったキーを使用して独自の関数を呼び出すと、何度も何度も呼び出されます。あまり良くない。エラー処理 (これは開発エラーです) を別のクラスに分割します。これにより、独自のエラー処理を処理できます。これは、関心の分離でもあります。

明らかに、さらに多くのフィードバックを追加できますが、これにより、アプローチを再考するための完全なスタートが得られると考えてください。良い解決策は 1 つだけではありませんが、この最初の概念を大幅に改善できることは確かです。

于 2012-04-11T15:40:58.443 に答える
0

2番目の質問は他の回答やコメントから明らかであるため、最初の質問に回答します(自分で回答するのは変だと思いますが、私の質問により適切な回答を見つけました)。私は両方を持つことができ、同時に内側または外側に反響します。コードは次のとおりです。

// Function to output language strings.
function text($Id)
    {
    // Already defined and tested that are valid (sql injection avoided also)
    global $Lang;
    global $FullUrl;

    $numargs = func_num_args(); // Get the number of arguments that are being passed.
    if ($numargs == 2)  // If there are actually two
        $Var=func_get_arg(1);   // Set $Var with the second value (1).

    if (is_int($Id))    // If a number is being passed
        {
        $results = mysql_query("SELECT * FROM translations WHERE id='$Id' AND page='$FullUrl'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang]) && !isset($Var)) echo $row[$Lang];  // If there is some, echo it
    elseif ($Var==1) return $row[$Lang];
        else error($FullUrl,$Lang); // Else, calls error function
        }

    else    // If a string is being passed
        {
        $results = mysql_query("SELECT * FROM htranslations WHERE keyword='$Id'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang]) && !isset($Var)) echo $row[$Lang];  // If it exists in the table, echo it
        elseif (!empty($row[$Lang]) && isset($Var)) return $row[$Lang];
        else    // Else (it doesn't exist)
            {
            $NewId = str_replace("_", " ", $Id);    // Replace the "_" with " "
            echo "<span style='color: red;' title='";   // Set a red color (warning)
            text(Wrong_sentence);   // Call this function and echo "This sentence could be wrong"
            echo "'>".$NewId."</span>"; // Echo the passed string with spaces
            error($FullUrl,$Lang,$Id);
            }
        }
    }

したがって、テキストを ECHO したい場合はtex(56)、 , text(Existing_string)orと書きtext(Non_existing_string)ます。しかし、これらの同じテキストを変数として返すにはtex(56,1)、 ,text(Existing_string,1)または"Non existing string". 「存在しない文字列」を使用するには、それを渡してそれ自体を返す必要がないことに注意してください。

そのコードにはまだ多くの問題がありますが、ご覧のとおり、学習して改善しています。これまでのところ、このコードは問題なく動作します。

于 2012-04-12T18:05:56.020 に答える