打開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()函數,就是在沒有導入模板名的情況下自動創建一個模板名。我個人有個感覺就是框架很多底層對函數有個檢測和判斷,可不可以把那些判斷刪去讓整個框架更加精簡。