質問
MySQLから取得したさまざまなタイプのリストをループして、Facebook風の「フィード」として表示する機能があります。リストのタイプごとに外観が異なるため、異なるテンプレートが必要です。
以下は、100回呼び出される可能性がある関数の例です(リストが100ある場合):
function display_listing($id,$type) {
global $abs_path;
switch($type) {
case 'photo':
include($abs_path . '/templates/photo.php');
break;
case 'video':
include($abs_path . '/templates/video.php');
break;
}
}
これを行うためのより良い方法はありますか?潜在的に100のインクルードにならない場合-プロセスが遅くなる可能性がありますか?ページでインクルードを何らかの方法で保存し、必要に応じて何度でも参照できますか?
...またはこれがベストプラクティスですか?
また、テンプレートエンジンなしで自分でこれを行う方法を知りたい...
編集:include_onceだけでは問題は解決しません(信じられません)...含まれるファイルを複数回再利用し、毎回変数を置き換えられる必要があります。
解決
スイッチはこのコードを記述するための最もスケーラブルな方法ではありませんが、テンプレートを別のファイルに保存する唯一の方法はここにあると思います。
おそらく、各テンプレートのコードを関数にカプセル化できます:
/*
photoTemplate.php
*/
<?php
function loadPhotoTemplate($id) {
?>
<div id="photo">
...
</div>
<?php
}
?>
/*
listing.php
*/
function display_listing($id,$type) {
global $abs_path;
switch($type) {
case 'photo':
include_once($abs_path . '/templates/photo.php');
loadPhotoTemplate($id);
break;
case 'video':
include_once($abs_path . '/templates/video.php');
loadVideoTemplate($id);
break;
}
}
これにより、各テンプレートファイルが最大で1回読み込まれ、そのアイテムの特定のデータを含むテンプレートを表示するたびに関数が呼び出されます。
編集
最初にすべてのテンプレートファイルをインクルードしてから、スイッチで適切な関数を呼び出すことをお勧めします。 PHPの* _once()関数は、呼び出されるたびに以前に含まれていた/必要なファイルのリストを調べる必要があるため、遅いです。
他のヒント
許可されたテンプレートの配列を作成します。リクエストされたテンプレートが配列内にあるかどうかを確認するために関数ルックをしてください。含まれている場合は、$ type変数を使用してファイルを含めます。はい、一般に、インクルードファイル名にユーザー指定のデータを使用するべきではありませんが、既知の適切な値の配列に対して検証したため、安全です。
パフォーマンスが懸念される場合、個人的にはこのループにはまったく入りません。
リスト内のアイテムが作成されるよりも頻繁に表示されると仮定すると、アイテムの作成時にHTMLを生成し、データベース内のデータとともに出力を保存します。 (または、memcacheまたはファイル、または他の場所にありますが、生成して保存します。)
その際、このロジックをアイテムの作成プロセスに戻して、同じ switch
ステートメントを実行しますが、一度に1つのアイテムのみを実行します。ループを抜けます。
表示時に、 display_listing()
を呼び出す代わりに、既に保存したHTMLをエコーアウトするだけです。
いくつかの点を検討する必要があると思います。まず、同じ「テンプレート」を含める可能性さえありますか? 100回?それはページに載せる膨大な量のコンテンツのようです。
小さな「スニペット」を使用している場合-たとえば、何度も繰り返されるテーブル行-私は、次のような文字列を返す関数を使用する傾向があります:
/* snippets.php */
function tableRow( $row )
{
return
'<tr><td>' . $row['var1'] . '</td>' .
'<td>' . $row['var2'] . '</td></tr>';
}
/* main page/view */
foreach ( $data as $row )
echo tableRow( $row );
ここでの主な利点は、関数にループとすべての並べ替えを含めることができることです。
単純な変数置換を探している場合、HTMLファイルに独自のミニテンプレートを作成できます。次のようなもの:
<p>{name}<br />
Posted {date} by {author}</p>
テンプレートを読み込んで、すべての{variables}で str_replace
を実行する display_listing
関数に文字列全体を渡します。パフォーマンスに大きな影響はないと思いますが、確実に試してみる必要があります。
include_once
を使用する場合 include
ではなく関数。
include_once()ステートメントには 指定されたファイルを評価します スクリプトの実行中。 これは次のような動作です include()ステートメント、唯一の 違いは、コードが ファイルは既に含まれています、それ 再び含まれません。として 名前が示唆する、それが含まれます 一度だけ。
異なるキーワードのスイッチを使用してテンプレートを含める場合は、スイッチに$ template_filenameなどの変数を設定し、スイッチから抜け出したら、次のようにインクルードします:
include_once("/templates/{$filename}.php");
インクルードをまったく使用したくない場合は、テンプレートエンジンを使用することもできます...
この方法は私にとっては理にかなっているようです。