zoukankan      html  css  js  c++  java
  • yii2的变量是如何注入到视图中去的?

    我对yii2的控制器中的变量如何渲染到视图中这个问题一直很好奇,另外,我还对yii2如何加载静态资源,如js和css比较好奇,于是趁着周末就看了下yii2的相关源码想把这两个问题都弄明白。变量如何渲染到视图中是弄明白了,但是静态资源的加载问题还是没有弄明白,做人不难太贪心,先把这个弄明白了,后续再说另一个。

    1,先把yii2中相关的关键代码贴出来看下

    yiiwebView继承了yiiaseView

    yii2的yiiaseView中的几个关键方法:

        public function render($view, $params = [], $context = null)
        {
            $viewFile = $this->findViewFile($view, $context);
            return $this->renderFile($viewFile, $params, $context);
        }
    
        public function renderFile($viewFile, $params = [], $context = null)
        {
            $viewFile = Yii::getAlias($viewFile);
            if ($this->theme !== null) {
                $viewFile = $this->theme->applyTo($viewFile);
            }
            if (is_file($viewFile)) {
                $viewFile = FileHelper::localize($viewFile);
            } else {
                throw new ViewNotFoundException("The view file does not exist: $viewFile");
            }
            $oldContext = $this->context;
            if ($context !== null) {
                $this->context = $context;
            }
            $output = '';
            $this->_viewFiles[] = $viewFile;
            if ($this->beforeRender($viewFile, $params)) {
                Yii::trace("Rendering view file: $viewFile", __METHOD__);
                $ext = pathinfo($viewFile, PATHINFO_EXTENSION);
                if (isset($this->renderers[$ext])) {
                    if (is_array($this->renderers[$ext]) || is_string($this->renderers[$ext])) {
                        $this->renderers[$ext] = Yii::createObject($this->renderers[$ext]);
                    }
                    /* @var $renderer ViewRenderer */
                    $renderer = $this->renderers[$ext];
                    $output = $renderer->render($this, $viewFile, $params);
                } else {
                    $output = $this->renderPhpFile($viewFile, $params);
                }
                $this->afterRender($viewFile, $params, $output);
            }
            array_pop($this->_viewFiles);
            $this->context = $oldContext;
            return $output;
        }
    
        public function renderPhpFile($_file_, $_params_ = [])
        {
            ob_start();
            ob_implicit_flush(false);
            extract($_params_, EXTR_OVERWRITE);
            require($_file_);
            return ob_get_clean();
        }

    我现在这个水平只是对代码(功能)的实现比较好奇,其实yii2框架代码的组织、框架设计都很值得学习,不过这都是后话,先把好奇的东西研究下。

    功能实现的关键就在renderPhpFile($_file_, $_params_ = [])这个方法里,而这个方法的关键又是:extract($_params, EXTR_OVERWRITE);,这个php函数的神奇之处在于,它可以将关联数组导入到一个变量表中,就是将数组键作为变量名、值作为变量的值进行赋值。比如下面这个简单的例子:

    Psy Shell v0.7.2 (PHP 5.6.29 — cli) by Justin Hileman 
    1
    >>> $arr = ['a' => 2, 'b' => 3]; 2 => [ 3 "a" => 2, 4 "b" => 3, 5 ] 6 >>> extract($arr); 7 => 2 8 >>> $a 9 => 2 10 >>> $b 11 => 3

    那么yii2视图中的变量值是怎么传递过来的也就很好理解了。

    2,变量注入过程的简单分析

    ob_start()打开输出缓冲区,这样php脚本中要输出的内容,比如变量值等,就不会输出到输出设备(如屏幕),而是存储到php自身的一个缓冲区中,在这些内容被冲刷出缓冲区之前,我们可以对这些内容进行操作,比如格式化下等。

    ob_implicit_flush(false)关闭内部的绝对(隐式)刷送,它的效果其实等同于调用flush()只不过如果打开它那就不用再主动调用flush()了,打开它将会在每次输出调用之后都会有一次刷送,那么在将变量注入到视图文件中时就需要关闭它,否则在视图还没渲染(可以理解为页面加载完成)完成时,这些变量就会输出到屏幕。

    extract($_params, EXTR_OVERWRITE);将控制器变量数组键值注入到对应的键名变量列表。

    require($_file);加载视图文件

    return ob_get_clean(); ob_get_clean()获取当前缓冲区内容,关闭(删除)当前的输出缓冲区。

    3,视图渲染过程的简单分析

    这个。。。时间有点儿晚了,有时间再说。

    参考资料:

    php手册

    yii2


  • 相关阅读:
    理解MySQL——索引与优化(转)
    C# 实现3Des加密 解密
    des加密解密源码 C# key值问题
    深入浅出mysql优化--一篇博客让你精通mysql优化策略--中
    深入浅出mysql优化--一篇博客让你精通mysql优化策略--上
    深入浅出mysql优化--了解mysql常用索引结构
    从零开始了解多线程 之 深入浅出AQS -- 下(Tools&CountDownLatch&CyclicBarrier&Semaphore)
    从零开始了解多线程 之 深入浅出AQS -- 上
    从零开始了解多线程知识之开始篇目 -- jvm&volatile
    利用doxygen提高源代码阅读效率
  • 原文地址:https://www.cnblogs.com/yangtoude/p/yii2-render-view.html
Copyright © 2011-2022 走看看