PHP 实现自己的模板引擎(三)——加入fetch方法

全栈 shanhuhai 1285℃ 0评论

上一篇,我们给出了一个简单的模板引擎的例子,通过 extract 函数将变量注入到当前作用域,通过 include 将模板文件引入,从而将变量注入到了模板,但是这种方法的问题是,我们无法拿到内容,内容直接输出到了浏览器端,这篇我们看看如何拿到模板解析后的内容。

缓存区控制函数

在PHP中有一类叫 “输出控制”的方法,他们基本都以 “ob” 开头,使用 ob_start 函数将开启一个输出缓存区,所有 echo print_r 等函数输出数据时,将会先被存储到到输出缓存区。

这个缓存区当然是一个看不到摸不着的东西,所以你可以把他想象成一个池子,所有输出函数输出的内容都会先被放到这个池子里,而不是直接输出到浏览器。

我们都知道如果一个文件中已经使用了 echo,print_r 这些方法, 再使用header(), setcookie() 这类需要发送heaer的函数会引起一个错误,但是当开启了输出缓存区,由于header等函数不会受缓存区影响,echo 等方法输出的内容将被缓存到缓存区,所以下面的代码将不会再引起错误,因为 echo 等函数的内容被放到了缓存区,而不是先于 header 等函数输出内容到了浏览器,所以不会报错,下面是示例代码

<?php

ob_start();
echo "Hello\n";
setcookie("cookiename", "项羽");
ob_end_flush();

?>

通过几个ob 函数来获取模板解析后的内容

我通过 ob 函数,将要输出到浏览器的内容放到 缓存区中,然后通过 ob_get_clean 函数可以获取到缓存区的内容,并且赋值给一个变量,这样我们就拿到了模板解析后的内容

看一个例子,将以下代码保存为 demo.php

<?php

$title  = "如果做一个模板引擎类" ;
$description = "简介";

ob_start();

require "tpl.php";

$output = ob_get_clean();
echo $output ;

再编写一个模板文件,将以下代码保存为 tpl.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>标题:<?php echo $title ?></h1>
    <p>简介: <?php echo $description ?> </p>
</body>
</html>

将这两个文件放到你的网站目录下,通过 url 访问
可以看到,通过ob 函数我们可以将 require 进来的模板内容,赋值到一个变量 $output

新的模板类

我们新增了一个 fetch 方法将代码进行了简单的重构,下面是新的 view.php 的代码, 代码如下


<?php /** * Author: shanhuhai * Date: 2017/7/27 19:29 * Mail: 441358019@qq.com */ namespace Lib; class View { /** * @var array 默认配置 */ protected $config = [ 'tplPath' => 'app/view', ]; /** * @var array 要注入到模板中的数据 */ protected $data = []; /** * 模板类的构造函数,接收一个配置数组 * View constructor. * @param array $config */ public function __construct(array $config) { $this->config = array_merge($this->config, $config); } /** * 添加要注入到模板中的数据 * @param array $data 要注入的数据 */ public function assign(array $data) { $this->data = array_merge($this->data, $data) ; } /** * 获取模渲染后的内容 * @param $tpl * @param array $data * @return string * @throws \Exception */ public function fetch($tpl, array $data = []) { $this->assign($data); ob_start(); //注入变量 extract($this->data); include $this->getTpl($tpl); $content = ob_get_clean(); ob_end_clean(); return $content; } /** * 渲染模板并输出 * @param string $tpl 模板位置 * @param array $data 要注入的数据 */ public function display($tpl, array $data = []) { $output = $this->fetch($tpl, $data); echo $output; } /** * 获取模板路径 * @param $tpl * @return string */ private function getTpl($tpl) { $tpl = $this->config['tplPath'].'/'.$tpl.'.php'; if(!file_exists($tpl)) { throw new \UnexpectedValueException("视图{$tpl}不存在"); } return $tpl; } }

下一篇我们将开始定义自己的模板语法,一些正则的知识是必须要的。

转载请注明:大后端 » PHP 实现自己的模板引擎(三)——加入fetch方法

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

表情

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

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