yii2佈局檔案裡有很多函式,你是否研究過他們都是幹嘛用的?這篇文章告訴你~
我們以安裝完yii2程式後預設的佈局為例說明
// @app/views/layouts/main.php
/* @var $this \yii\web\View */
/* @var $content string */
use yii\helpers\Html;
use yii\widgets\Breadcrumbs;
use app\assets\AppAsset;
AppAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<div class="wrap">
<div class="container">
<?= $content ?>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="pull-left">© My Company <?= date('Y') ?></p>
<p class="pull-right"><?= Yii::powered() ?></p>
</div>
</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>複製程式碼
首先要說的是,佈局其實就是檢視,一種特殊的檢視而已,所以我們明說佈局函式,實質在說檢視類View。
我就是我 $this
既然是一種特殊的檢視,所以佈局裡面的 $this 物件其實就是當前檢視本身,這在預設佈局的註釋裡已經說明。
/* @var $this \yii\web\View */
/* @var $content string */複製程式碼
所以我建議你在閱讀本文的時候,開啟yii\web\View原始碼同步進行。
寫啥是啥 $content
這是在佈局檔案裡除了 $this 外的第二個變數,我們都知道佈局就像一個容器一樣將基礎架構先畫出來,然後想用此結構的檢視直接使用就可以了,那麼 $content 就是使用此佈局的檢視自己的內容。
開山函式 beginPage 和 endPage
記住,所有的HTML我們都應該包含在 beginPage 和 endPage 函式之間,它們代表一個頁面的開始和結束。
之外它們還分別觸發了下面的兩個事件
View::EVENT_BEGIN_PAGE
View::EVENT_END_PAGE複製程式碼
如果你想統計檢視頁面內程式碼的渲染時間,可以在這兩個事件上做做手腳。當然,endPage的作用要更加大,後面會單獨拿出來說明。
資源在哪我說的算 head()
確切的說,該函式只是告訴了yii要將資原始檔(比如js和css)放到頁面的哪裡,一般它在head標籤內,如果你將它移到其他地方,你會發現將來頁面的js檔案和css檔案等也轉移了。
head有啥我來做 renderHeadHtml()
從名字你就可以知道,它負責將頭部的一些程式碼渲染出來,比如js和css等檔案的具體html標籤,具體放哪?那必須是放到head()函式裡指定的位置了,另外,這是一個protected型別方法,你不要想著能直接->就呼叫它,沒門,它僅僅為View類的其他方法服務。
beginBody 和 endBody
這兩個函式和 beginPage 和 endPage 有雷同的地方,就是做了兩個標記,代表body的開始和結束,作為位置標籤,另外也觸發了兩個事件
View::EVENT_BEGIN_BODY
View::EVENT_END_BODY複製程式碼
當然 endBody 和 endPage 一樣,還有其他職責,放到最後說,你先了解他們代表開始和結束,同時觸發事件即可。
中場總結
上面說了 head、beginBody、endBody 都具有標籤的作用,View為其設計了3個常量作為代表,分別如下
PH_HEAD // $this->head()
PH_BODY_BEGIN // $this->beginBody()
PH_BODY_END // $this->endBody複製程式碼
根據我們上面的瞭解,先畫一個圖出來,看看佈局的視覺化樣子。
// 我是圖
$this->beginPage()
- <html>
-- <head>
$this->head() // PH_HEAD
-- </head>
-- <body>
$this->beginBody() // PH_BODY_BEGIN
$content
$this->endBody() // PH_BODY_END
-- </body>
- </html>
$this->endPage()複製程式碼
renderBodyBeginHtml 和 renderBodyEndHtml 函式
上面我們知道有一個叫做 renderHeadHtml 方法負責往 PH_HEAD 位置放資原始檔,那麼PH_BODY_BEGIN和PH_BODY_END 也應該同類待遇,renderBodyBeginHtml和renderBodyEndHtml就是幹這個的。
而從程式碼來看 renderBodyBeginHtml 和 renderBodyEndHtml 做的事情和 renderHeadHtml 差不多,都是資源的具體程式碼話,你是否記得我們在兄弟連時候有一節( nai8.me/course-vide… )說過關於asset資源類位置的問題(指定資源在頁面的上部還是下部),對,renderBodyBeginHtml、renderBodyEndHtml 等就是做這個的。
我們分條說下
- renderBodyBeginHtml渲染的是位置為 POS_BEGIN 的js檔案
- renderBodyEndHtml渲染的是位置為 POS_END、POS_READY、POS_LOAD的js檔案
- renderHeadHtml渲染的是位置為POS_HEAD的js檔案和所有css檔案(無位置功能)以及一些head的metaTags。
現在你明白了吧,到此刻,你知道了有三個函式負責三個位置的程式碼渲染,而這些渲染其實就是資源的程式碼實現。
再說endPage
到現在,萬事俱備,但是東風在哪裡?它就是endPage
看一部分endPage的原始碼我們
echo strtr($content, [
self::PH_HEAD => $this->renderHeadHtml(),
self::PH_BODY_BEGIN => $this->renderBodyBeginHtml(),
self::PH_BODY_END => $this->renderBodyEndHtml($ajaxMode),
]);複製程式碼
endPage活生生的實現了程式碼和位置之間的替換,說白了就是字串替換。。。
當然,在View類裡還有一些小方法,比如registerJs()、clear()等等,阿北相信當你瞭解了佈局(檢視)形成的流程後,這些很容易看懂,如果還不懂,請留言此貼問。
最後一個例子
如果我們把最後相應給客戶的頁面比作一棟大樓。那麼看看角色的分類
- 佈局 代表大樓圖紙(代表著一個框架)
- 資源類 代表購物清單
- View的三個render函式 代表具體的建築工人,採購資源類,並放到大樓裡。
- endPage函式,就是售樓許可證,保證所有資源都到位。
- 使用佈局的檢視 就是人,入駐大樓,沒有檢視的佈局都是紙老虎。
(完)
本文原創釋出於微信公眾號 北哥小報 , 嚴謹的原創技術文,Q群:171277552。