PHP 实现自己的模板引擎(四)——自定义模板语法

全栈 shanhuhai 2018℃ 0评论

现在你应该知道如何做一个模板引擎类了,只不过使用原生的 php 做模板语法。

看下面代码

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

    <!-- 打印变量 -->
    <h1><?php echo $title ?></h1>

    <!-- 添件判断 -->
    <?php if($show): ?>
    <button>显示</button>
    <?php endif; ?>

    <!-- 循环 -->
    <ul>
    <?php foreach($rows as $row): ?>
        <li><?php echo $row ?></li>
    <?php endforeach  ?>
    </ul>
</body>
</html>

看吧,打印变量,循环,判断都有了,由于 php 本身就是一门模板语言,所以对于大部分情况也就够用了。

但是如果你学过 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


<?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 类里,你可以尝试以下,这是很好的锻炼,如果遇到问题,可以我留言。

好了这个系列算写完了,希望你能有所收获。

转载请注明:大后端 » PHP 实现自己的模板引擎(四)——自定义模板语法

喜欢 (2)or分享 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址