袁来如此的工作笔记
袁来如此的工作笔记
竹杖芒鞋轻胜马,谁怕? 一蓑烟雨任平生。

php模板引擎自定义模板语法

浏览量:80

如果你学过 Smarty, Twig 等模板引擎,你可能会好奇,它们那样的模板语法是如果实现的?

如果有一个答案的话,我只能说,其实他们自定义的模板语法不管设计的多么优雅华丽,最终还是要被转换成 “ 这样的代码块的, 因为只有这样的代码才能被 PHP 解析执行,那么如何转换,答案就是用正则啊。

实现 Smarty 的foreach 语法
我们都知道 smarty 下的循环的语法是这样的

    {foreach from=$myArray item=foo}
    <li>{$foo}</li>
    {/foreach}
好,我们下面来用一个例子来展示,这种语法是如何实现的。

首先创建一个模板文件,保存为 tpl.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>


<ul>
     {foreach from=$names item=name}
    <li>{$name}</li>
    {/foreach}
</ul>


</body>
</html>
注意这回我把模板文件的后缀保持成了.html,因为这回模板文件里真的没有 php 代码了,都是html和我们自定义的模板语法.
然后创建demo.php

$rules =  array(

        '/{\/(foreach)}/i' => '<?php } ?>',
        '/{foreach\s+from=(\S+)\s+item=(\S+)}/is' => '<?php if(is_array($1)) foreach($1 as $$2) { ?>',
        '/{\s*(\S+)\s*}/is' =>  '<?php echo $1;?>',

    );

//-- 解析模板 start
$html = file_get_contents('tpl.html');
$html = preg_replace(array_keys($rules), $rules, $html);

//-- 缓存解析后的模板
file_put_contents('tpl_cache.php', $html);

//-- 要注入模板的变量
$data = ['names'=>['李白', '花木兰']];

//-- 注入变量
extract($data);

//-- 引入解析的模板
include 'tpl_cache.php';


可以在命令行运行php demo.php

这个例子完整的展示了读取模板文件,解析模板文件,然后将解析后的文件保存为.php 后缀的 tpl_cache.php ,所以你在运行程序后生成的 tpl_cache.php 中可以看到,tpl.html 中的自定义模板语法,最终还是被解析成了原生的php 语法,这样我们才可以将变量注入进去。

我没有打算用这种自定义的语法来实现自己的类,我觉得 php 的原生语法已经感觉很好了,使用原生的好处是你可以获取比较大的自由度,而且也免去了模板解析的消耗,当你的模板语法设计的越复杂时,模板解析也越慢,你的正则可能也越容易出错,所以也推荐你使用原生的模板语法。

当然你如果你想把这个新的特性加到我们的 view.php 类里,你可以尝试以下,这是很好的锻炼,如果遇到问题,可以我留言。
打赏