2

複数行の SQL クエリ結果のレンダリングを高速化するために、PHP でデータ プロバイダー クラスを作成しています。基本的に、このクラスには一連の SQL 関連のプロパティとメソッドがあり、データのページ付け、並べ替え、最終的なレンダリングに役立ちます。後者に関しては、行を簡単にテンプレート化できるようにしたいので、行テンプレート ファイルをパラメーターとしてビュー ファイル (MVC モデル内) から呼び出すことができる render() というメソッドを作成しました。これは次のようになります。

public function render($row_template_file) {
    if($result = mysql_query($this->query)) {
        while($row = mysql_fetch_array($result)) {
            include $row_template_file;
        }
    }
}

実際の方法はそれよりも洗練されています (テンプレート ファイルが存在するかどうかをチェックし、mysql_* 関数ではなくデータ抽象化クラスを使用するなど)、一般的な考え方は理解できます。行テンプレート ファイルは基本的に HTML であり、出力に直接送信されます。つまり、次のようになります。

<div class="row">
    <div class="foo"><?php echo $row['foo']; ?></div>
    <div class="bar"><?php echo $row['bar']; ?></div>
</div>

このアプローチは問題なく機能します。唯一の問題は、特に多数の行をレンダリングする場合に、ループ内の include() がパフォーマンス上の優れたアイデアではないことです。そのように行をテンプレート化する機能を維持しながら、それを置き換えることができるものはありますか? ここには同様の質問がほとんどありませんでしたが、提案されたすべての解決策には、私が避けたいロジックとプレゼンテーションの混合が含まれていました。最初の反復中に匿名関数を作成し、その後のすべての反復でそれを呼び出すことを考えていましたが、考えすぎているか、ここで車輪を再発明している可能性があります。何か案は?

4

5 に答える 5

1

提案されたprintf()/sprintf()ソリューションはきちんとしていますが、たとえば次のようなプレゼンテーション固有のロジックをテンプレートに含めることはできません。

<div class="gender">
    <?php if($row['gender'] == 'f') : ?>
    <img src="female_icon.gif" />
    <?php else : ?>
    <img src="male_icon.gif" />
    <?php endif; ?>
</div>

テンプレートが「基本的にHTML」であると書くべきではありませんでした:-)

私は質問で言及した匿名関数ソリューションで遊んでいますが、見た目はあまり良くありませんが、機能し、複数のインクルードよりも大幅に高速であるため、これを可能な回答の1つとして追加しています:

public function render($row_template_file) {
    if($result = mysql_query($this->query)) {
        $render_row = create_function('$row', '?>'.file_get_contents($row_template_file).'<?php ');
        while($row = mysql_fetch_array($result)) {
            $render_row($row);
        }
    }
}
于 2012-04-18T20:12:56.793 に答える
1

おそらく、代わりに php の printf() / sprintf()関数を使用しますか?

したがって、テンプレート ファイルには次のようなコードが含まれます。

<div class="row">
    <div class="foo">%s</div>
    <div class="bar">%s</div>
</div>

ループの前に、変数に一度だけロードします。

$tmpl = file_get_contents( $row_template_file);

ループ内では、変数をテンプレートに入れるだけです。

printf( $tmpl, $row['foo'], $row['bar']);

上記のリンクの例 #3 と #4 を参照してください。「引数の交換」 — テンプレートで番号付きの位置を使用する方法 — 異なるテンプレートで引数の順序が異なることを心配しないでください。

それがうまくいくことを願っています。

于 2012-04-18T11:44:55.863 に答える
0

これはほとんど簡単すぎる解決策のように感じます。おそらく私は大きな問題が何であるかわからないかもしれませんが、PHP関数を使用するのはどうですか?

function outputRow($row) {
    echo '<div class="row">';
    echo '<div class="foo">' . $row['foo'] . '</div>';
    echo '<div class="bar">' . $row['bar'] . '</div>';
    echo '</div>';
}

そして、含める代わりに、あなたはoutputRow($row)

于 2012-04-18T11:41:39.697 に答える
0

プレースホルダーを含む文字列としてテンプレートを作成し、値をそれに置き換えます。メソッドに渡しrender()ます。

次に、どのように文字列を取得するのが最善かを決定する必要があります-経由でfile_get_contents(私はこれに行きます)、または単に「テンプレート」クラスにハードコーディングし、そこからインターフェイスを抽出します-そしてそれを渡します。

于 2012-04-18T11:46:58.570 に答える
0

eval関数で遊んでみるかもしれません。php.net に関するこのコメントが役立つかもしれません: http://www.php.net/manual/ru/function.eval.php#108091

于 2012-04-19T08:03:30.700 に答える