模板文件缓存之调用视图驱动篇

一、 缓存参数定义

设置缓存目录

thinkphp/base.php

// 定义渲染模板文件缓存目录
defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);
// 定义编译文件缓存目录
defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);

设置缓存参数

application/config.php

'cache' => [
	// 驱动方式
	'type'   => 'File',
	// 缓存保存目录
	'path'   => CACHE_PATH,
	// 缓存前缀
	'prefix' => '',
	// 缓存有效期 0表示永久缓存
	'expire' => 0,
]

二、 输出页面

调用视图实例,展示页面

application/admin/controller/auth/Admin.php

public function index()
{
	// 这里调用视图类的fetch方法,返回渲染后的模板,见解析和获取模板内容,用于输出
    return $this->view->fetch();
}

解析和获取模板内容,用于输出

thinkphp/library/think/View.php

/**
 * 解析和获取模板内容 用于输出
 * @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(); // 当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中。
    ob_implicit_flush(0); // 关闭隐式刷送,绝对(隐式)刷送将导致在每次输出调用后有一次刷送操作,以便不再需要对 flush() 的显式调用。

    // 渲染输出
    try {
    	// 使用display可以传入模板文件内容字符串$content,使用fetch是使用已设计好的模板文件
        $method = $renderContent ? 'display' : 'fetch';
        // 允许用户自定义模板的字符串替换
        $replace = array_merge($this->replace, $replace, (array) $this->engine->config('tpl_replace_string'));
        // ↓调用视图驱动thinkphp/library/think/view/driver/Think.php
        $this->engine->config('tpl_replace_string', $replace);
        $this->engine->$method($template, $vars, $config);
    } catch (\Exception $e) {
    	// 清空缓冲区并关闭输出缓冲
        ob_end_clean();
        throw $e;
    }

    // 得到当前缓冲区的内容并清空,并关闭当前输出缓冲,ob_get_clean() 实质上是一起执行了ob_get_contents() 和 ob_end_clean()。
    $content = ob_get_clean();
    // 内容过滤标签
    Hook::listen('view_filter', $content);
    // 返回渲染后的模板
    return $content;
}

接着上面的代码,对调用视图驱动做下简要分析,第一个调用config方法,配置模板引擎参数

thinkphp/library/think/view/driver/Think.php

/**
 * 配置或者获取模板引擎参数
 * @access private
 * @param string|array  $name 参数名
 * @param mixed         $value 参数值
 * @return mixed
 */
public function config($name, $value = null)
{
    if (is_array($name)) {
        $this->template->config($name);
        $this->config = array_merge($this->config, $name);
    } elseif (is_null($value)) {
        return $this->template->config($name);
    } else {
    	// 设置模板引擎(thinkphp/library/think/Template.php)的参数tpl_replace_string为替换字符串,因为该变量不存在,所以会调用魔术方法__set,来设置引擎配置$this->config的tpl_replace_string
        $this->template->$name = $value;
        // 设置模板驱动$this->config的tpl_replace_string为替换字符串
        $this->config[$name]   = $value;
    }
}

这里就是上面提到的魔术方法

thinkphp/library/think/Template.php

/**
 * 模板引擎参数赋值
 * @access public
 * @param mixed $name
 * @param mixed $value
 */
public function __set($name, $value)
{
    $this->config[$name] = $value;
}

第二个调用fetch方法,渲染模板文件

thinkphp/library/think/view/driver/Think.php

/**
 * 渲染模板文件
 * @access public
 * @param string    $template 模板文件
 * @param array     $data 模板变量
 * @param array     $config 模板参数
 * @return void
 */
public function fetch($template, $data = [], $config = [])
{
	// 如果模板文件的扩展名为''
    if ('' == pathinfo($template, PATHINFO_EXTENSION)) {
        // 获取模板文件名,见自动定位模板文件
        // $template = D:\phpstudy\PHPTutorial\WWW\fastadmin\public/../application/admin\view\auth\admin\index.html
        $template = $this->parseTemplate($template);
    }
    // 模板不存在 抛出异常
    if (!is_file($template)) {
        throw new TemplateNotFoundException('template not exists:' . $template, $template);
    }
    // 记录视图信息
    App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info');
    // 调用模板引擎(thinkphp/library/think/Template.php)渲染模板文件,见调用模板引擎篇
    // 这里调用后,会输出渲染后的模板
    $this->template->fetch($template, $data, $config);
}
/**
 * 自动定位模板文件
 * @access private
 * @param string $template 模板文件规则
 * @return string
 */
private function parseTemplate($template)
{
    // 分析模板文件规则
    $request = Request::instance();
    // 获取视图根目录,如果模板文件名包含@,则会调用其他模块的模板文件,如$this->fetch('admin@member/edit');
    if (strpos($template, '@')) {
        // 跨模块调用
        list($module, $template) = explode('@', $template);
    }
    // 如果设置了view_base,此目录作为所有视图文件的根目录,模块作为子目录
    if ($this->config['view_base']) {
        // 基础视图目录
        $module = isset($module) ? $module : $request->module();
        $path   = $this->config['view_base'] . ($module ? $module . DS : '');
    } else {// 如果没设置,视图文件存放在每个模块的view目录下面{view_path:模板起始路径,默认为''}
    	// $path = D:\phpstudy\PHPTutorial\WWW\fastadmin\public/../application/admin\view\
        $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path'];
    }
	// view_depr:模板文件名分隔符,默认为 DIRECTORY_SEPARATOR
    $depr = $this->config['view_depr'];
    // 如果模板文件名不包含 /
    if (0 !== strpos($template, '/')) {
    	// 将模板文件名中的 / 和 : 替换成目录分隔符
        $template   = str_replace(['/', ':'], $depr, $template);
        // 字符串命名风格转换,将 Java 风格转换为 C 的风格
        // $controller = auth.admin
        $controller = Loader::parseName($request->controller());
        if ($controller) {
        	// ①如果模板文件名为空,按照默认规则定位{auto_rule:1 解析为小写+下划线,2 全部转换小写}
            if ('' == $template) {
                // $template = auth\admin\index
                $template = str_replace('.', DS, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action());
            } elseif (false === strpos($template, $depr)) {// ②如果模板文件名不为空,且不包含目录分隔符,如$this->fetch('edit'); 
            	// $template = auth\admin\edit
                $template = str_replace('.', DS, $controller) . $depr . $template;
            }
        }
    } else {// ③如果模板文件存在目录分隔符,且处于第一个字符,如$this->fetch('/menu');
    	// $template = menu
        $template = str_replace(['/', ':'], $depr, substr($template, 1));
    }
    // view_suffix = html,下面为三种模板目录分隔类型
    // ① D:\phpstudy\PHPTutorial\WWW\fastadmin\public/../application/admin\view\auth\admin\index.html
    // ② D:\phpstudy\PHPTutorial\WWW\fastadmin\public/../application/admin\view\auth\admin\edit.html
    // ③ D:\phpstudy\PHPTutorial\WWW\fastadmin\public/../application/admin\view\menu.html
    return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值