打开thinkphp/library/view这个类,我们来随便聊一聊thinkphp5这个版本的模板引擎和输出。
* * * * *
> 第一个淡然就是我们的构造函数。其实thinkphp5一开始就有为我们定义一些全局函数,就像tp3那样。比如我们如果做个权限控制的话,就可以直接使用
~~~
/**
* 架构函数
* @access public
* @param array $engine 模板引擎参数
* @param array $replace 字符串替换参数
*/
public function __construct($engine = [], $replace = [])
{
// 初始化模板引擎
$this->engine((array) $engine);
// 基础替换字符串
$request = Request::instance();
$base = $request->root();
$root = strpos($base, '.') ? ltrim(dirname($base), DS) : $base;
if ('' != $root) {
$root = '/' . ltrim($root, '/');
}
$baseReplace = [
'__ROOT__' => $root,
'__URL__' => $base . '/' . $request->module() . '/' . Loader::parseName($request->controller()),
'__STATIC__' => $root . '/static',
'__CSS__' => $root . '/static/css',
'__JS__' => $root . '/static/js',
];
$this->replace = array_merge($baseReplace, (array) $replace);
}
~~~
在这里,ThinkPHP5为我们定义了一些全局变量。一般类似于__CSS__这样的全局变量我们给前台模板使用。当我们使用后台资源的时候,我们一般在app\admin下建立config.php定义模板变量。
* * * * *
> 下面我们看一下,ThinkPHP5输出函数的用法
~~~
/**
* 模板变量静态赋值
* @access public
* @param mixed $name 变量名
* @param mixed $value 变量值
* @return void
*/
public static function share($name, $value = '')
{
if (is_array($name)) {
self::$var = array_merge(self::$var, $name);
} else {
self::$var[$name] = $value;
}
}
/**
* 模板变量赋值
* @access public
* @param mixed $name 变量名
* @param mixed $value 变量值
* @return $this
*/
public function assign($name, $value = '')
{
if (is_array($name)) {
$this->data = array_merge($this->data, $name);
} else {
$this->data[$name] = $value;
}
return $this;
}
~~~
看下这两个函数有什么区别呢。首先,share和assign函数,都可以往$name函数中导入数组。assign(array('$string' => '$value'))类似这样的用法。
~~~
/**
* 解析和获取模板内容 用于输出
* @param string $template 模板文件名或者内容
* @param array $vars 模板输出变量
* @param array $replace 替换内容
* @param array $config 模板参数
* @param bool $renderContent 是否渲染内容
* @return string
* @throws Exception
*/
public function fetch($template = '', $vars = [], $replace = [], $config = [], $renderContent = false)
{
// 模板变量
$vars = array_merge(self::$var, $this->data, $vars);
// 页面缓存
ob_start();
ob_implicit_flush(0);
// 渲染输出
$method = $renderContent ? 'display' : 'fetch';
$this->engine->$method($template, $vars, $config);
// 获取并清空缓存
$content = ob_get_clean();
// 内容过滤标签
Hook::listen('view_filter', $content);
// 允许用户自定义模板的字符串替换
$replace = array_merge($this->replace, $replace);
if (!empty($replace)) {
$content = strtr($content, $replace);
}
return $content;
}
/**
* 视图内容替换
* @access public
* @param string|array $content 被替换内容(支持批量替换)
* @param string $replace 替换内容
* @return $this
*/
public function replace($content, $replace = '')
{
if (is_array($content)) {
$this->replace = array_merge($this->replace, $content);
} else {
$this->replace[$content] = $replace;
}
return $this;
}
/**
* 渲染内容输出
* @access public
* @param string $content 内容
* @param array $vars 模板输出变量
* @param array $replace 替换内容
* @param array $config 模板参数
* @return mixed
*/
public function display($content, $vars = [], $replace = [], $config = [])
{
return $this->fetch($content, $vars, $replace, $config, true);
}
~~~
> 这里我们可以看到,display对fetch函数实现了一个兼容。如果习惯使用tp3的display()函数的朋友还是可以继续使用display()输出。对于旧版本的tp3老函数,tp5做了很多兼容。下面我们来看下更简洁的view()函数。
~~~
if (!function_exists('view')) {
/**
* 渲染模板输出
* @param string $template 模板文件
* @param array $vars 模板变量
* @param array $replace 模板替换
* @param integer $code 状态码
* @return \think\response\View
*/
function view($template = '', $vars = [], $replace = [], $code = 200)
{
return Response::create($template, 'view', $code)->replace($replace)->assign($vars);
}
}
~~~
同学们有空可以看一看helper.php这个助手函数库,里面有很多文档没有写但是非常好用的函数。比如说每个控制器里大量使用的 return view()函数,就是在没有导入模板名的情况下自动创建一个模板名。我个人有个感觉就是框架很多底层对函数有个检测和判断,可不可以把那些判断删去让整个框架更加精简。