欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

构建PHP框架之构建模版引擎实例

程序员文章站 2022-04-14 23:05:59
...
自从来到新公司就一直很忙,最近这段时间终于稍微闲了一点,赶紧接着写这个系列,感觉再不写就烂尾了。

之前我们说到,拿到{{ $name }}这样一段内容时,我们只需要将它转化成<?php echo $name ?>这样,就可以识别了,输出相应的变量值。

那就要需要正则匹配{{ $name }},然后替换掉{{}},分别替换成<?php echo?>

但是要想到一个问题,如果我在 view 里写了 php 的代码,其中含有{{ $name }},也会被替换。例子如下:

<?php$name = 'test';$str = "{{ $name }}";?>

要解决这个问题,我们需要将 PHP 的代码去掉,只留下 html 代码再做替换的处理。幸好 PHP 有一个方法 token_get_all,会将提供的内容按 PHP 标记进行分割。使用此方法解析如下内容:

$content = <<<VIEW<?php\$name = 'test';\$str = "{{ \$name }}";?><html>  <body>{{ \$name }}</body><html>VIEW;print_r(token_get_all($content));

这里$符号前加\是为了转移,在真正是现实不需要。结果如下:

Array
(
    [0] => Array
        (
            [0] => 379
            [1] => <?php
            [2] => 1
        )
    [1] => Array
        (
            [0] => 382
            [1] =>
            [2] => 2
        )
    [2] => =
    [3] => Array
        (
            [0] => 382
            [1] =>
            [2] => 2
        )
    [4] => Array
        (
            [0] => 323
            [1] => 'test'
            [2] => 2
        )
    [5] => ;
    [6] => Array
        (
            [0] => 382
            [1] =>
            [2] => 2
        )
    [7] => =
    [8] => Array
        (
            [0] => 382
            [1] =>
            [2] => 3
        )
    [9] => "
    [10] => Array
        (
            [0] => 322
            [1] => {{
            [2] => 3
        )
    [11] => Array
        (
            [0] => 320
            [1] => $name
            [2] => 3
        )

    [12] => Array
        (
            [0] => 322
            [1] =>  }}
            [2] => 3
        )
    [13] => "
    [14] => ;
    [15] => Array
        (
            [0] => 382
            [1] =>
            [2] => 3
        )
    [16] => Array
        (
            [0] => 381
            [1] => ?>
            [2] => 4
        )
    [17] => Array
        (
            [0] => 321
            [1] =>
<html>
  <body>{{ $name }}</body>
<html>
            [2] => 5
        )

)

可以看到 PHP 相关的代码被解析了,我们只需要判断出是 html 代码,然后做替换就可以了。其中的321就是定义好的常量T_INLINE_HTML的值,标记解析出来的就是 html 代码。

我们定义view文件的后缀为sf,那我们就可以在controller/model/view目录下创建view.sf文件,内容如下

<?php$title = 'It is a title';$str = "{{ $title }}";?><html>
    <head>
        <title>{{ $title }}</title>
    <head>
    <body>
        <h2>{{ $str }}</h2>
        <p>{{ $body }}<p>
    </body>
</html>

然后我们来改造Controller中的render方法,代码如下

public function render($view, $params = [])
{
    $file = '../views/' . $view . '.sf';
    $fileContent = file_get_contents($file);
    $result = '';
    foreach (token_get_all($fileContent) as $token) {
        if (is_array($token)) {
            list($id, $content) = $token;
            if ($id == T_INLINE_HTML) {
                $content = preg_replace('/{{(.*)}}/', '<?php echo $1 ?>', $content);
            }
            $result .= $content;
        } else {
            $result .= $token;
        }
    }
    $generatedFile = '../runtime/cache/' . md5($file);
    file_put_contents($generatedFile, $result);
    extract($params);
    require_once $generatedFile;
}

修改actionView如下

public function actionView(){$this->render('site/view', ['body' => 'Test body information']);}

访问 http://localhost/simple-framework/public/index.php?r=site/view ,得到如下页面
构建PHP框架之构建模版引擎实例

今天就先到这里。项目内容和博客内容也都会放到Github上,欢迎大家提建议。

code:

blog project:

以上就是构建PHP框架之构建模版引擎实例的详细内容,更多请关注其它相关文章!