简体   繁体   English

在PHP中,有更好的方法来进行动态模板制作

[英]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_splitpreg_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM