溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

View視圖怎么在PHP中使用

發(fā)布時間:2020-12-19 14:32:42 來源:億速云 閱讀:214 作者:Leah 欄目:開發(fā)技術

今天就跟大家聊聊有關View視圖怎么在PHP中使用,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

視圖名

渲染視圖時,可指定一個視圖名或視圖文件路徑/別名,大多數(shù)情況下使用前者因為前者簡潔靈活, 我們稱用名字的視圖為 視圖名.

視圖名可以依據(jù)以下規(guī)則到對應的視圖文件路徑:

視圖名可省略文件擴展名,這種情況下使用 .php 作為擴展, 視圖名 about 對應到 about.php 文件名;
視圖名以雙斜杠 // 開頭,對應的視圖文件路徑為 @app/views/ViewName, 也就是說視圖文件在 yii\base\Application::viewPath 路徑下找, 例如 //site/about 對應到 @app/views/site/about.php。
視圖名以單斜杠/開始,視圖文件路徑以當前使用模塊 的yii\base\Module::viewPath開始, 如果不存在模塊,使用@app/views/ViewName開始,例如,如果當前模塊為user, /user/create 對應成@app/modules/user/views/user/create.php, 如果不在模塊中,/user/create對應@app/views/user/create.php。
如果 yii\base\View::context 渲染視圖 并且上下文實現(xiàn)了 yii\base\ViewContextInterface, 視圖文件路徑由上下文的 yii\base\ViewContextInterface::getViewPath() 開始, 這種主要用在控制器和小部件中渲染視圖,例如 如果上下文為控制器SiteController,site/about 對應到 @app/views/site/about.php。
如果視圖渲染另一個視圖,包含另一個視圖文件的目錄以當前視圖的文件路徑開始, 例如被視圖@app/views/post/index.php 渲染的 item 對應到 @app/views/post/item。
根據(jù)以上規(guī)則,在控制器中 app\controllers\PostController 調(diào)用 $this->render('view'), 實際上渲染@app/views/post/view.php 視圖文件,當在該視圖文件中調(diào)用 $this->render('_overview') 會渲染@app/views/post/_overview.php 視圖文件。

視圖中訪問數(shù)據(jù)

在視圖中有兩種方式訪問數(shù)據(jù):推送和拉取。

推送方式是通過視圖渲染方法的第二個參數(shù)傳遞數(shù)據(jù),數(shù)據(jù)格式應為名稱-值的數(shù)組, 視圖渲染時,調(diào)用PHP extract() 方法將該數(shù)組轉(zhuǎn)換為視圖可訪問的變量。 例如,如下控制器的渲染視圖代碼推送2個變量到 report 視圖:$foo = 1 和 $bar = 2。

echo $this->render('report', [
  'foo' => 1,
  'bar' => 2,
]);

拉取方式可讓視圖從yii\base\View視圖組件或其他對象中主動獲得數(shù)據(jù)(如Yii::$app), 在視圖中使用如下表達式$this->context可獲取到控制器ID, 可讓你在report視圖中獲取控制器的任意屬性或方法,如以下代碼獲取控制器ID。

The controller ID is: <?= $this->context->id ?>
?>

推送方式讓視圖更少依賴上下文對象,是視圖獲取數(shù)據(jù)優(yōu)先使用方式, 缺點是需要手動構建數(shù)組,有些繁瑣,在不同地方渲染時容易出錯。

視圖間共享數(shù)據(jù)

yii\base\View視圖組件提供yii\base\View::params參數(shù)屬性來讓不同視圖共享數(shù)據(jù)。

例如在about視圖中,可使用如下代碼指定當前breadcrumbs的當前部分。

$this->params['breadcrumbs'][] = 'About Us';

在布局文件(也是一個視圖)中,可使用依次加入到y(tǒng)ii\base\View::params數(shù)組的值來 生成顯示breadcrumbs:

<?= yii\widgets\Breadcrumbs::widget([
  'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>

布局

布局是一種特殊的視圖,代表多個視圖的公共部分,例如,大多數(shù)Web應用共享相同的頁頭和頁尾, 在每個視圖中重復相同的頁頭和頁尾,更好的方式是將這些公共放到一個布局中, 渲染內(nèi)容視圖后在合適的地方嵌入到布局中。

創(chuàng)建布局

由于布局也是視圖,它可像普通視圖一樣創(chuàng)建,布局默認存儲在@app/views/layouts路徑下, 模塊中使用的布局應存儲在yii\base\Module::basePath模塊目錄 下的views/layouts路徑下,可配置yii\base\Module::layoutPath來自定義應用或模塊的布局默認路徑。

如下示例為一個布局大致內(nèi)容,注意作為示例,簡化了很多代碼, 在實際中,你可能想添加更多內(nèi)容,如頭部標簽,主菜單等。

<?php
use yii\helpers\Html;

/* @var $this yii\web\View */
/* @var $content string 字符串 */
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <?= Html::csrfMetaTags() ?>
  <title><?= Html::encode($this->title) ?></title>
  <?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
  <header>My Company</header>
  <?= $content ?>
  <footer>&copy; 2014 by My Company</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

如上所示,布局生成每個頁面通用的HTML標簽,在<body>標簽中,打印$content變量, $content變量代表當yii\base\Controller::render()控制器渲染方法調(diào)用時傳遞到布局的內(nèi)容視圖渲染結果。

大多數(shù)視圖應調(diào)用上述代碼中的如下方法,這些方法觸發(fā)關于渲染過程的事件, 這樣其他地方注冊的腳本和標簽會添加到這些方法調(diào)用的地方。

  • yii\base\View::beginPage(): 該方法應在布局的開始處調(diào)用, 它觸發(fā)表明頁面開始的 yii\base\View::EVENT_BEGIN_PAGE 事件。

  • yii\base\View::endPage(): 該方法應在布局的結尾處調(diào)用, 它觸發(fā)表明頁面結尾的 yii\base\View::EVENT_END_PAGE 時間。

  • yii\web\View::head(): 該方法應在HTML頁面的<head>標簽中調(diào)用, 它生成一個占位符,在頁面渲染結束時會被注冊的頭部HTML代碼(如,link標簽, meta標簽)替換。

  • yii\web\View::beginBody(): 該方法應在<body>標簽的開始處調(diào)用, 它觸發(fā) yii\web\View::EVENT_BEGIN_BODY 事件并生成一個占位符, 會被注冊的HTML代碼(如JavaScript)在頁面主體開始處替換。

  • yii\web\View::endBody(): 該方法應在<body>標簽的結尾處調(diào)用, 它觸發(fā) yii\web\View::EVENT_END_BODY 事件并生成一個占位符, 會被注冊的HTML代碼(如JavaScript)在頁面主體結尾處替換。

布局中訪問數(shù)據(jù)

在布局中可訪問兩個預定義變量:$this 和 $content,前者對應和普通視圖類似的yii\base\View 視圖組件 后者包含調(diào)用yii\base\Controller::render()方法渲染內(nèi)容視圖的結果。

如果想在布局中訪問其他數(shù)據(jù),必須使用視圖中訪問數(shù)據(jù)一節(jié)介紹的拉取方式, 如果想從內(nèi)容視圖中傳遞數(shù)據(jù)到布局,可使用視圖間共享數(shù)據(jù)一節(jié)中的方法。

使用布局

如控制器中渲染一節(jié)描述,當控制器調(diào)用yii\base\Controller::render() 方法渲染視圖時,會同時使用布局到渲染結果中,默認會使用@app/views/layouts/main.php布局文件。

可配置yii\base\Application::layout 或 yii\base\Controller::layout 使用其他布局文件, 前者管理所有控制器的布局,后者覆蓋前者來控制單個控制器布局。 例如,如下代碼使 post 控制器渲染視圖時使用 @app/views/layouts/post.php 作為布局文件, 假如layout 屬性沒改變,控制器默認使用 @app/views/layouts/main.php 作為布局文件。

namespace app\controllers;

use yii\web\Controller;

class PostController extends Controller
{
  public $layout = 'post';

  // ...
}

對于模塊中的控制器,可配置模塊的 yii\base\Module::layout 屬性指定布局文件應用到模塊的所有控制器。

由于layout 可在不同層級(控制器、模塊,應用)配置,在幕后Yii使用兩步來決定控制器實際使用的布局。

第一步,它決定布局的值和上下文模塊:

如果控制器的 yii\base\Controller::layout 屬性不為空null,使用它作為布局的值, 控制器的 yii\base\Controller::module模塊 作為上下文模塊。
如果 yii\base\Controller::layout 為空,從控制器的祖先模塊(包括應用) 開始找 第一個yii\base\Module::layout 屬性不為空的模塊,使用該模塊作為上下文模塊, 并將它的yii\base\Module::layout 的值作為布局的值, 如果都沒有找到,表示不使用布局。
第二步,它決定第一步中布局的值和上下文模塊對應到實際的布局文件,布局的值可為:

路徑別名 (如 @app/views/layouts/main).
絕對路徑 (如 /main): 布局的值以斜杠開始,在應用的[[yii\base\Application::layoutPath|layout path] 布局路徑 中查找實際的布局文件,布局路徑默認為 @app/views/layouts。
相對路徑 (如 main): 在上下文模塊的yii\base\Module::layoutPath布局路徑中查找實際的布局文件, 布局路徑默認為yii\base\Module::basePath模塊目錄下的views/layouts 目錄。
布爾值 false: 不使用布局。
布局的值沒有包含文件擴展名,默認使用 .php作為擴展名。

嵌套布局

有時候你想嵌套一個布局到另一個,例如,在Web站點不同地方,想使用不同的布局, 同時這些布局共享相同的生成全局HTML5頁面結構的基本布局,可以在子布局中調(diào)用 yii\base\View::beginContent() 和yii\base\View::endContent() 方法,如下所示:

<?php $this->beginContent('@app/views/layouts/base.php'); ?>

...child layout content here...

<?php $this->endContent(); ?>

如上所示,子布局內(nèi)容應在 yii\base\View::beginContent() 和 yii\base\View::endContent() 方法之間,傳給 yii\base\View::beginContent() 的參數(shù)指定父布局,父布局可為布局文件或別名。

使用以上方式可多層嵌套布局。

使用數(shù)據(jù)塊

數(shù)據(jù)塊可以在一個地方指定視圖內(nèi)容在另一個地方顯示,通常和布局一起使用, 例如,可在內(nèi)容視圖中定義數(shù)據(jù)塊在布局中顯示它。

調(diào)用 yii\base\View::beginBlock() 和 yii\base\View::endBlock() 來定義數(shù)據(jù)塊, 使用 $view->blocks[$blockID] 訪問該數(shù)據(jù)塊,其中 $blockID 為定義數(shù)據(jù)塊時指定的唯一標識ID。

如下實例顯示如何在內(nèi)容視圖中使用數(shù)據(jù)塊讓布局使用。

首先,在內(nèi)容視圖中定一個或多個數(shù)據(jù)塊:

...

<?php $this->beginBlock('block1'); ?>

...content of block1...

<?php $this->endBlock(); ?>

...

<?php $this->beginBlock('block3'); ?>

...content of block3...

<?php $this->endBlock(); ?>

然后,在布局視圖中,數(shù)據(jù)塊可用的話會渲染數(shù)據(jù)塊,如果數(shù)據(jù)未定義則顯示一些默認內(nèi)容。

...
<?php if (isset($this->blocks['block1'])): ?>
  <?= $this->blocks['block1'] ?>
<?php else: ?>
  ... default content for block1 ...
<?php endif; ?>

...

<?php if (isset($this->blocks['block2'])): ?>
  <?= $this->blocks['block2'] ?>
<?php else: ?>
  ... default content for block2 ...
<?php endif; ?>

...

<?php if (isset($this->blocks['block3'])): ?>
  <?= $this->blocks['block3'] ?>
<?php else: ?>
  ... default content for block3 ...
<?php endif; ?>
...

使用視圖組件

yii\base\View視圖組件提供許多視圖相關特性,可創(chuàng)建yii\base\View或它的子類實例來獲取視圖組件, 大多數(shù)情況下主要使用 view應用組件,可在應用配置中配置該組件, 如下所示:

[
  // ...
  'components' => [
    'view' => [
      'class' => 'app\components\View',
    ],
    // ...
  ],
]

視圖組件提供如下實用的視圖相關特性,每項詳情會在獨立章節(jié)中介紹:

  • 主題: 允許為你的Web站點開發(fā)和修改主題;

  • 片段緩存: 允許你在Web頁面中緩存片段;

  • 客戶腳本處理: 支持CSS 和 JavaScript 注冊和渲染;

  • 資源包處理: 支持 資源包的注冊和渲染;

  • 模板引擎: 允許你使用其他模板引擎,如 Twig, Smarty。

開發(fā)Web頁面時,也可能頻繁使用以下實用的小特性。

設置頁面標題

每個Web頁面應有一個標題,正常情況下標題的標簽顯示在 布局中, 但是實際上標題大多由內(nèi)容視圖而不是布局來決定,為解決這個問題, yii\web\View 提供 yii\web\View::title 標題屬性可讓標題信息從內(nèi)容視圖傳遞到布局中。

為利用這個特性,在每個內(nèi)容視圖中設置頁面標題,如下所示:

<?php
$this->title = 'My page title';
?>
然后在視圖中,確保在 <head> 段中有如下代碼:

<title><?= Html::encode($this->title) ?></title>

注冊Meta元標簽

Web頁面通常需要生成各種元標簽提供給不同的瀏覽器,如<head>中的頁面標題,元標簽通常在布局中生成。

如果想在內(nèi)容視圖中生成元標簽,可在內(nèi)容視圖中調(diào)用yii\web\View::registerMetaTag()方法,如下所示:

<?php
$this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php']);
?>

以上代碼會在視圖組件中注冊一個 "keywords" 元標簽,在布局渲染后會渲染該注冊的元標簽, 然后,如下HTML代碼會插入到布局中調(diào)用yii\web\View::head()方法處:

<meta name="keywords" content="yii, framework, php">

注意如果多次調(diào)用 yii\web\View::registerMetaTag() 方法,它會注冊多個元標簽,注冊時不會檢查是否重復。

為確保每種元標簽只有一個,可在調(diào)用方法時指定鍵作為第二個參數(shù), 例如,如下代碼注冊兩次 "description" 元標簽,但是只會渲染第二個。

$this->registerMetaTag(['name' => 'description', 'content' => 'This is my cool website made with Yii!'], 'description');
$this->registerMetaTag(['name' => 'description', 'content' => 'This website is about funny raccoons.'], 'description');

注冊鏈接標簽

和 Meta標簽 類似,鏈接標簽有時很實用,如自定義網(wǎng)站圖標,指定Rss訂閱,或授權OpenID到其他服務器。 可以和元標簽相似的方式調(diào)用yii\web\View::registerLinkTag(),例如,在內(nèi)容視圖中注冊鏈接標簽如下所示:

$this->registerLinkTag([
  'title' => 'Live News for Yii',
  'rel' => 'alternate',
  'type' => 'application/rss+xml',
  'href' => 'http://www.yiiframework.com/rss.xml/',
]);

上述代碼會轉(zhuǎn)換成

復制代碼 代碼如下:

<link title="Live News for Yii" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/">


和 yii\web\View::registerMetaTag() 類似, 調(diào)用yii\web\View::registerLinkTag() 指定鍵來避免生成重復鏈接標簽。

視圖事件

yii\base\View 視圖組件會在視圖渲染過程中觸發(fā)幾個事件, 可以在內(nèi)容發(fā)送給終端用戶前,響應這些事件來添加內(nèi)容到視圖中或調(diào)整渲染結果。

  • yii\base\View::EVENT_BEFORE_RENDER: 在控制器渲染文件開始時觸發(fā), 該事件可設置 yii\base\ViewEvent::isValid 為 false 取消視圖渲染。

  • yii\base\View::EVENT_AFTER_RENDER: 在布局中調(diào)用 yii\base\View::beginPage() 時觸發(fā), 該事件可獲取yii\base\ViewEvent::output的渲染結果,可修改該屬性來修改渲染結果。

  • yii\base\View::EVENT_BEGIN_PAGE: 在布局調(diào)用 yii\base\View::beginPage() 時觸發(fā);

  • yii\base\View::EVENT_END_PAGE: 在布局調(diào)用 yii\base\View::endPage() 是觸發(fā);

  • yii\web\View::EVENT_BEGIN_BODY: 在布局調(diào)用 yii\web\View::beginBody() 時觸發(fā);

  • yii\web\View::EVENT_END_BODY: 在布局調(diào)用 yii\web\View::endBody() 時觸發(fā)。

例如,如下代碼將當前日期添加到頁面結尾處:

\Yii::$app->view->on(View::EVENT_END_BODY, function () {
  echo date('Y-m-d');
});

渲染靜態(tài)頁面

靜態(tài)頁面指的是大部分內(nèi)容為靜態(tài)的不需要控制器傳遞動態(tài)數(shù)據(jù)的Web頁面。

可將HTML代碼放置在視圖中,在控制器中使用以下代碼輸出靜態(tài)頁面:

public function actionAbout()
{
  return $this->render('about');
}

如果Web站點包含很多靜態(tài)頁面,多次重復相似的代碼顯得很繁瑣, 為解決這個問題,可以使用一個在控制器中稱為 yii\web\ViewAction 的獨立操作。 例如:

namespace app\controllers;

use yii\web\Controller;

class SiteController extends Controller
{
  public function actions()
  {
    return [
      'page' => [
        'class' => 'yii\web\ViewAction',
      ],
    ];
  }
}

現(xiàn)在如果你在@app/views/site/pages目錄下創(chuàng)建名為 about 的視圖, 可通過如下rul顯示該視圖:

http://localhost/index.php?r=site/page&view=about
GET 中 view 參數(shù)告知 yii\web\ViewAction 操作請求哪個視圖,然后操作在 @app/views/site/pages目錄下尋找該視圖,可配置 yii\web\ViewAction::viewPrefix 修改搜索視圖的目錄。

最佳實踐

視圖負責將模型的數(shù)據(jù)展示用戶想要的格式,總之,視圖

  • 應主要包含展示代碼,如HTML, 和簡單的PHP代碼來控制、格式化和渲染數(shù)據(jù);

  • 不應包含執(zhí)行數(shù)據(jù)查詢代碼,這種代碼放在模型中;

  • 應避免直接訪問請求數(shù)據(jù),如 $_GET, $_POST,這種應在控制器中執(zhí)行, 如果需要請求數(shù)據(jù),應由控制器推送到視圖。

  • 可讀取模型屬性,但不應修改它們。

  • 為使模型更易于維護,避免創(chuàng)建太復雜或包含太多冗余代碼的視圖,可遵循以下方法達到這個目標:

  • 使用 布局 來展示公共代碼(如,頁面頭部、尾部);

  • 將復雜的視圖分成幾個小視圖,可使用上面描述的渲染方法將這些小視圖渲染并組裝成大視圖;

  • 創(chuàng)建并使用 小部件 作為視圖的數(shù)據(jù)塊;

  • 創(chuàng)建并使用助手類在視圖中轉(zhuǎn)換和格式化數(shù)據(jù)。

看完上述內(nèi)容,你們對View視圖怎么在PHP中使用有進一步的了解嗎?如果還想了解更多知識或者相關內(nèi)容,請關注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI