yii2的變量是如何注入到視圖中去的?


我對yii2的控制器中的變量如何渲染到視圖中這個問題一直很好奇,另外,我還對yii2如何加載靜態資源,如js和css比較好奇,於是趁着周末就看了下yii2的相關源碼想把這兩個問題都弄明白。變量如何渲染到視圖中是弄明白了,但是靜態資源的加載問題還是沒有弄明白,做人不難太貪心,先把這個弄明白了,后續再說另一個。

1,先把yii2中相關的關鍵代碼貼出來看下

yii\web\View繼承了yii\base\View

yii2的yii\base\View中的幾個關鍵方法:

    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

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM