[英]In PHP is there a better way to do dynamic templating
I'm creating module for an application which will have simple custom templating with tags that will be replaced with data from a database. 我正在为应用程序创建模块,该应用程序将具有简单的自定义模板,这些模板带有将被数据库中的数据替换的标签。 The field names will be different in each instance of this module. 在此模块的每个实例中,字段名称将不同。 I want to know if there is a better way to do this. 我想知道是否有更好的方法可以做到这一点。
The code below is what I've come up with, But I believe there must be a better way. 下面的代码是我想出的,但是我相信必须有更好的方法。 I struggled with preg_split and preg_match_all and just hit my limit so I did it the dumb person way. 我在preg_split和preg_match_all方面苦苦挣扎,只是达到了极限,所以我做到了愚蠢的人。
<?php
$customTemplate = "
<div>
<<This>>
<<that>>
</div>
";
function process_template ($template, $begin = '<<', $end = '>>') {
$begin_exploded = explode($begin, $template);
if (is_array($begin_exploded)) {
foreach ($begin_exploded as $key1 => $value1) {
$end_exploded = explode($end, $value1);
if (is_array($end_exploded)) {
foreach ($end_exploded as $key2 => $value2) {
$tag = $begin.$value2.$end;
$variable = trim($value2);
$find_it = strpos($template,$tag);
if ($find_it !== false) {
//str_replace ($tag, $MyClass->get($variable), $template );
$template = str_replace ($tag, $variable, $template);
}
}
}
}
}
return $template;
}
echo(process_template($customTemplate));
/* Will Echo
<div>
This
that
</div>
*/
?>
In the future I will connect $MyClass->get() to replace the tag with the proper data. 将来,我将连接$ MyClass-> get()以用适当的数据替换标记。 And the custom template will be built by the user. 定制模板将由用户构建。
Rather than preg_split
or preg_match
I would rather use preg_replace_callback
, since you are doing replacements, and the replacement value is derived from what looks like will end up being a method in another class. 我宁愿使用preg_replace_callback
而不是preg_split
或preg_match
,因为您正在进行替换,并且替换值是从看起来像是另一个类中的方法的结果派生的。
function process_template($template, $begin = '<<', $end = '>>') {
// get $MyClass in the function scope somehow. Maybe pass it as another parameter?
return preg_replace_callback("/$begin(\w+)$end/", function($var) use ($MyClass) {
return $MyClass->get($var[1]);
}, $template);
}
Here's an example to play with: https://3v4l.org/N1p03 这是一个示例: https : //3v4l.org/N1p03
I assume this is just for fun/learning. 我认为这只是为了娱乐/学习。 If I really needed to use a template for something I would rather start with composer require "twig/twig:^2.0"
instead. 如果确实需要使用模板,那么我宁愿从composer require "twig/twig:^2.0"
开始,也composer require "twig/twig:^2.0"
。 In fact, if you're interested in learning more about how it works you could go check out a well-established system like twig or blade does it. 实际上,如果您有兴趣了解有关其工作原理的更多信息,可以查看完善的系统,例如树枝或刀片服务器。 ( Better than I've done it in this answer. ) ( 比我在此答案中所做的要好。 )
There are tons templating engines around, but sometimes... just add complexity and dependencies for a maybe simple thing. 周围有大量的模板引擎,但是有时...只是为一件简单的事情增加了复杂性和依赖性。 This a modified sample of what I used for make some javascript corrections. 这是我用来进行一些JavaScript更正的修改后的示例。 This works for your template. 这适用于您的模板。
function process_template($html,$b='<<',$e='>>'){
$replace=['this'=>'<input name="this" />','that'=>'<input name="that" />'];
if(preg_match_all('/('.$b.')(.*?)('.$e.')/is',$html,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE)){
$t='';$o=0;
foreach($matches as $m){
//for reference $m[1][0] contains $b, $m[2][0] contains $e
$t.=substr($html,$o,$m[0][1]-$o);
$t.=$replace[$m[2][0]];
$o=$m[3][1]+strlen($m[3][0]);
}
$t.=substr($html,$o);
$html=$t;
}
return $html;
}
$html="
<div>
<<this>>
<<that>>
</div>
";
$new=process_template($html);
echo $new;
For demo purpose I put the array $replace
that handling the substitutions. 出于演示目的,我将数组$replace
为替换对象。 You replace those with your function that will handle the replacement. 您用将处理替换的函数替换它们。
Here is a working snippet: https://3v4l.org/MBnbR 这是一个有效的代码段: https : //3v4l.org/MBnbR
I like this function because you have control of what to replace and what to put back on the final result. 我喜欢此功能,因为您可以控制要替换的内容以及返回最终结果的内容。 By the way by using the PREG_OFFSET_CAPTURE
also return on the matches the position where the regexp groups happens. 顺便说一下,通过使用PREG_OFFSET_CAPTURE
还可以在匹配项上返回正则表达式组发生的位置。 Those are on the $m[x][1]
. 这些在$m[x][1]
。 The captured text will be on $m[x][0]
. 捕获的文本将在$m[x][0]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.