// ---------- 簡易テンプレートエンジン関数 ----------
function template_engin($html,$dataArray){
// 入力データを順番に置換({と}は再帰的に処理しないようエスケープ)
foreach ($dataArray as $key => $value){
$value = str_replace( '{', '{', $value);
$value = str_replace( '}', '}', $value);
$html = str_replace( '{{'.$key.'}}', $value, $html);
}
// テンプレート上に残った専用タグを除去
$html=preg_replace('/{{.*}}/','',$html);
// 変換されたデータを返す
return $html;
}
==== プログラム例 ====
下記2つのファイルをPHPの動作するディレクトリに保存して、ブラウザでtemplate.phpを表示するとテンプレートの専用タグの一に出力データが表示されます。
$value){
$value = str_replace( '{', '{', $value);
$value = str_replace( '}', '}', $value);
$html = str_replace( '{{'.$key.'}}', $value, $html);
}
$html=preg_replace('/{{.*}}/','',$html);
return $html;
}
// ---------- メイン ----------
// テンプレートファイルの読み込み
$fileTemp = file_get_contents('template.html');
// テンプレート出力用の連想配列初期化
$dataArray=array();
// 出力データを登録(外部ユーザーの入力値はhtmlspecialcharsする事)
$dataArray['title']='デモタイトル';
$dataArray['data'] =date("Y/m/d H:i:s");
$dataArray['text'] =htmlspecialchars('Hello World!',ENT_QUOTES,'UTF-8');
$dataArray['html']='Google';
//テンプレート関数実行
$output=template_engin($fileTemp,$dataArray);
//表示
echo $output;
{{title}}
{{title}}
日付:{{data}}
通常文書:{{text}}
HTML許可:{{html}}
未使用キーは除去→:{{hogehoge}}
===== カスタマイズ =====
単純にデータを展開するだけだと芸が無いので「HTML許可選択」を追加行っています。専用タグのキー名の頭に@をつけるとHTML許可して、@が無ければHTMLを不許可にしています。
==== プログラム ====
下記のtemplate.phpとtemplate.htmlは同じフォルダに保存してください。(template.htmlはファイルパスを書き換えれば任意のディレクトリに移動できます)
$value){
//html有効
$html=$value;
$html = str_replace( '{', '{', $html);
$html = str_replace( '}', '}', $html);
$data = str_replace( '{{@'.$key.'}}', $html, $data);
//html無効
$xss=htmlspecialchars($value,ENT_QUOTES,'UTF-8');
$xss = str_replace( '{', '{', $xss);
$xss = str_replace( '}', '}', $xss);
$data = str_replace( '{{'.$key.'}}', $xss, $data);
}
//未変換タグ除去
$data=preg_replace('/{{.*}}/','',$data);
//変換されたデータを返す
return $data;
}
// ---------- 関数終了----------
// テンプレート出力用の連想配列初期化
$temp_array=array();
// テンプレートファイルの読み込み
$temp_data = file_get_contents('template.html');
// 適当に$output に配列名とデータを登録
$temp_array['title']='デモタイトル';
$temp_array['data']=date("Y/m/d H:i:s");
$temp_array['text']='Hello World!';
$temp_array['html']='Google';
//テンプレート関数実行
$output=template_engin($temp_data,$temp_array);
echo $output;
{{title}}
{{title}}
日付:{{data}}
通常文書:{{text}}
HTML許可:{{@html}}
HTML不許可:{{html}}
未使用キーは除去:{{hogehoge}}
==== 説明 ====
入力したテンプレートファイル中にある「%%{{title}}%%」や「%%{[html]}%%」などのタグを、配列変数$temp_array['title']や$temp_array['html']の内容に置き換えます。
** 専用タグ **
* %%{{@配列キー名}}%%・・・HTML許可
* %%{{配列キー名}}%%・・・HTML禁止
**問題点**
1.配列が多くなれば変換速度は低下します。
2.テンプレートが長くなれば変換速度は低下します。
2.テンプレート中で「%%{{文字列}}%%」 はテンプレートタグと扱われますので使用できません。またテンプレートタグとして使用しなかった「%%{{文字列}}%%」は全て削除されます。テンプレートと中で「%%{{文字列}}%%」を表示したい場合は実体参照を利用して下さい(例:「%%{{文字列}}%%」)
3.挿入データ中の 「%%{%%」 と 「%%}%%」 は二重展開を防止するため「%%{%%」と「%%}%%」に置き換えられます。したがって挿入データ中で「%%{{タグ}}%%」を使用しても再展開されません。
4.キー名にはPHPの配列で認められている文字しか使えません(安全な文字列は英文字またはアンダースコアから始まり、英文字・数字・アンダースコアの文字列です)
**更新**
2018/09/13 挿入データのタグ文字(「%%{%%」「%%}%%」)のエスケープ方法を変更 : 以前は「%%{{%%」や「%%}}%%」の2回連続カッコを対象に文字列のみ実体参照に変換していましたが1文字でもエスケープするように変換しました。