yii2佈局文件裏有不少函數,你是否研究過他們都是幹嗎用的?這篇文章告訴你~php
咱們以安裝完yii2程序後默認的佈局爲例說明css
// @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。html
既然是一種特殊的視圖,因此佈局裏面的 $this 對象其實就是當前視圖自己,這在默認佈局的註釋裏已經說明。web
/* @var $this \yii\web\View */
/* @var $content string */複製代碼
因此我建議你在閱讀本文的時候,打開yii\web\View源代碼同步進行。ajax
這是在佈局文件裏除了 $this 外的第二個變量,咱們都知道佈局就像一個容器同樣將基礎架構先畫出來,而後想用此結構的視圖直接使用就能夠了,那麼 $content 就是使用此佈局的視圖本身的內容。微信
記住,全部的HTML咱們都應該包含在 beginPage 和 endPage 函數之間,它們表明一個頁面的開始和結束。yii2
以外它們還分別觸發了下面的兩個事件架構
View::EVENT_BEGIN_PAGE
View::EVENT_END_PAGE複製代碼
若是你想統計視圖頁面內代碼的渲染時間,能夠在這兩個事件上作作手腳。固然,endPage的做用要更加大,後面會單獨拿出來講明。app
確切的說,該函數只是告訴了yii要將資源文件(好比js和css)放到頁面的哪裏,通常它在head標籤內,若是你將它移到其餘地方,你會發現未來頁面的js文件和css文件等也轉移了。框架
從名字你就能夠知道,它負責將頭部的一些代碼渲染出來,好比js和css等文件的具體html標籤,具體放哪?那必須是放到head()函數裏指定的位置了,另外,這是一個protected類型方法,你不要想着能直接->就調用它,沒門,它僅僅爲View類的其餘方法服務。
這兩個函數和 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()複製代碼
上面咱們知道有一個叫作 renderHeadHtml 方法負責往 PH_HEAD 位置放資源文件,那麼PH_BODY_BEGIN和PH_BODY_END 也應該同類待遇,renderBodyBeginHtml和renderBodyEndHtml就是幹這個的。
而從代碼來看 renderBodyBeginHtml 和 renderBodyEndHtml 作的事情和 renderHeadHtml 差很少,都是資源的具體代碼話,你是否記得咱們在兄弟連時候有一節( nai8.me/course-vide… )說過關於asset資源類位置的問題(指定資源在頁面的上部仍是下部),對,renderBodyBeginHtml、renderBodyEndHtml 等就是作這個的。
咱們分條說下
如今你明白了吧,到此刻,你知道了有三個函數負責三個位置的代碼渲染,而這些渲染其實就是資源的代碼實現。
到如今,萬事俱備,可是東風在哪裏?它就是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()等等,阿北相信當你瞭解了佈局(視圖)造成的流程後,這些很容易看懂,若是還不懂,請留言此貼問。
若是咱們把最後相應給客戶的頁面比做一棟大樓。那麼看看角色的分類
(完)
本文原創發佈於微信公衆號 北哥小報 , 嚴謹的原創技術文,Q羣:171277552。