2

PHPで単純なテンプレートレイヤーを書いていますが、少し行き詰まっています。現時点での仕組みは次のとおりです。

まずfetch_template、データベースからテンプレートの内容をロードするために使用します-これは機能します(興味があれば、起動時にすべてのテンプレートを収集します)。

テンプレートコードとロジックでPHP変数を使用しています-例:

// PHP:
$name = 'Ross';

// Tpl:
<p>Hello, my name is $name.</p>

次に、output_template(以下)を使用して、テンプレート内の変数を解析し、それらを置き換えます。以前は、栄光のstr_replaceテンプレートクラスでテンプレートタグを使用していましたが、非効率的でした。

/**
 * Returns a template after evaluating it
 * @param   string  $template   Template contents
 * @return  string  Template output
 */
function output_template($template) {
    eval('return "' . $template . '";');
}

私の問題は、まだ推測していない場合、変数が関数内で宣言されていないことです-したがって、$templateグローバルスコープに配置しない限り、関数は変数を解析できません-これを実行したいかどうかはわかりません。それまたは関数のパラメーターとして変数の配列を持っている(これはさらに退屈に聞こえますが、可能です)。

関数を使用するのではなく、関数のコード(ワンライナーのみ)をコードで使用する以外の解決策はありますか?

ありがとう、ロス

追伸私はSmartyとそこにある幅広いテンプレートエンジンについて知っています-私はそれらを使用するつもりはないので、それらを提案しないでください。ありがとう!

4

4 に答える 4

8

ループを実行するのではなく、を使用できますinclude($template_name)

または、テンプレートからの出力のコンテンツが必要な場合は、次のようにすることができます。

$template_name = 'template.php';

// import the contents into this template
ob_start();
include($template_name);
$content = ob_get_clean();

// do something with $content now ...

また、テンプレートでは、見過ごされがちなPHP構文を使用できることを忘れないでください。

<?php if ($a == 5): ?>
A is equal to 5
<?php endif; ?>

テンプレート内のデータを操作するのに最適なif、while、for、foreach、およびswitch...の代替構文を使用できます。詳細については、「制御構造の代替構文」を参照してください。

于 2008-11-15T10:49:48.420 に答える
6

置換する変数を含む連想配列を渡してから、それらをextract()します。

次に、$ _ GLOBALSを渡して、同じ結果を得ることができます。

function output_template($template, $vars) {
    extract($vars);
    eval('return "' . $template . '";');
}

編集:テンプレートの作成を許可されているユーザーと、ロードするテンプレートを指定しているユーザーによっては、evalではなく文字列の置換を検討することもできます。次に、エスケープにも問題がある可能性があります...

于 2008-11-15T10:41:10.903 に答える
3

また、davevのコメント評価を拡張するのは少し醜いです。

あなたが次のようなことをすることができれば

function inc_scope( $file , $vars )
{
    extract($vars); 
    ob_start(); 
    require($file); 
    return ob_get_clean(); 
}

次に、テンプレート言語としてplain-old-phpを使用するようになり、悪意のあるものは取得されません。「extract」+バッファリングは、require内のphpコードの表示範囲を制限するだけです。

于 2008-11-15T10:47:03.247 に答える