視圖是 MVC 架構中負責資料呈現的核心元件。Yii 框架透過 yii\web\View 應用元件提供完整的視圖管理與渲染機制。本文系統性介紹視圖建立、安全性、組織結構、各情境渲染方式,幫助開發者全面掌握 Yii 視圖系統。
視圖本質為 PHP 腳本檔案,包含 HTML 與表現層 PHP 程式碼:
title = 'Login'; ?>= Html::encode($this->title) ?>
Please fill out the following fields to login:
= $form->field($model, 'username') ?> = $form->field($model, 'password')->passwordInput() ?> = Html::submitButton('Login') ?>
$this:yii\web\View 實例,管理視圖渲染$model、$form 等:從控制器或其他物件傳入的資料在視圖檔案頂部以註解標註預定義變數型別,可獲得 IDE 智慧提示並自動生成文件:
/* @var $this yii\web\View */ /* @var $model app\models\Post */ /* @var $comments app\models\Comment[] */
= Html::encode($user->name) ?>
= HtmlPurifier::process($post->text) ?>
HtmlPurifier 安全性佳但效能較差,高流量應用建議快取過濾結果:
// 快取範例
$key = 'purified_' . md5($post->text);
$content = Yii::$app->cache->get($key);
if ($content === false) {
$content = HtmlPurifier::process($post->text);
Yii::$app->cache->set($key, $content, 3600);
}
echo $content;
| 渲染者 | 預設視圖目錄 | 範例 |
|---|---|---|
| 控制器 | @app/views/ControllerID | PostController → @app/views/post |
| 模組控制器 | ModulePath/views/ControllerID | admin/UserController → @app/modules/admin/views/user |
| Widget | WidgetPath/views | app\widgets\Menu → @app/widgets/views |
覆寫 yii\base\ViewContextInterface::getViewPath() 方法:
class PostController extends Controller {
public function getViewPath() {
return '@app/views/custom-post';
}
}
| 方法 | 使用版面配置 | 適用場景 |
|---|---|---|
render() | 是 | 一般頁面渲染 |
renderPartial() | 否 | 局部渲染、AJAX 回應(不含 JS/CSS) |
renderAjax() | 否 | AJAX 回應(含註冊的 JS/CSS) |
renderFile() | 否 | 指定完整路徑或別名渲染 |
namespace app\controllers;
use Yii;
use app\models\Post;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
class PostController extends Controller {
public function actionView($id) {
$model = Post::findOne($id);
if ($model === null) {
throw new NotFoundHttpException;
}
// 渲染 view 視圖並套用版面配置
return $this->render('view', [
'model' => $model,
]);
}
}
Widget 視圖無版面配置支援,$this 指向 Widget 實例:
// 視圖檔案位於 WidgetPath/views/
// 使用 CWidget::render() 渲染
// 使用 Widget 兩種方式
beginWidget('path.to.WidgetClass'); ?>
...body content...
endWidget(); ?>
// 或無 body 內容
widget('path.to.WidgetClass'); ?>
// 帶參數配置
widget('CMaskedTextField', ['mask' => '99/99/9999']); ?>
class MyWidget extends CWidget {
public function init() {
// beginWidget() 時呼叫
}
public function run() {
// endWidget() 時呼叫,輸出內容
$this->render('myview', ['data' => $this->data]);
}
}
| 方法 | 說明 |
|---|---|
$this->render('_overview') | 渲染同目錄下視圖,相對路徑 |
$this->renderAjax('_form') | AJAX 渲染,包含 JS/CSS |
$this->renderFile('@app/views/shared/_menu.php') | 指定絕對路徑/別名渲染 |
// 透過應用元件存取視圖
echo \Yii::$app->view->renderFile('@app/views/site/license.php');
action-name.php(kebab-case)_partial-name.php(底線開頭)layout-name.php(存放於 layouts 目錄)// 控制器中
return $this->render('view', [
'model' => $model,
'comments' => $model->comments, // 關聯資料
'tags' => $model->tags, // 避免視圖中查詢
]);
public function actionView($id) {
$model = $this->findModel($id);
if (Yii::$app->request->isAjax) {
$this->layout = false; // AJAX 請求不使用版面配置
}
return $this->render('view', ['model' => $model]);
}
// 片段快取
if ($this->beginCache('post-' . $model->id, ['duration' => 3600])) {
// 快取內容
echo $this->render('_post_content', ['model' => $model]);
$this->endCache();
}
A: 檢查視圖路徑慣例、控制器 ID 對應、模組路徑設定。使用 getViewPath() 除錯確認實際路徑。
A: 透過 $this->context 存取控制器實例:$this->context->generateUrl()。
A: Widget 視圖中 $this 指向 Widget,需透過參數傳遞或 Yii::$app->controller 存取控制器。
Yii 視圖系統提供豐富的渲染選項與彈性的組織結構。核心重點在於:
掌握這些概念後,開發者能建構出安全、可維護且高效能的表現層架構。