承接上篇,本文以 demos/hangman 猜字遊戲為例,分析 YII 從請求進入到視圖渲染輸出的完整流程,重點剖析 CController::render() 如何結合版面配置與局部視圖產生最終 HTML。
$yii = dirname(__FILE__) . '/../../framework/yii.php';
$config = dirname(__FILE__) . '/protected/config/main.php';
Yii::createWebApplication($config)->run();
main.php 設定預設控制器 game、URL 管理規則等。
CWebApplication::__construct() → configure($config) 將設定陣列映射為屬性。run() → processRequest() → runController('') 解析路由。GameController,執行預設動作 actionPlay()。public function actionPlay() {
$levels = ['10'=>'Easy...', '5'=>'Medium...', '3'=>'Hard...'];
if (isset($_POST['level']) && isset($levels[$_POST['level']])) {
// 初始化遊戲狀態
$this->render('guess'); // 顯示猜字頁面
} else {
$params = ['levels'=>$levels, 'error'=>Yii::app()->request->isPostRequest];
$this->render('play', $params); // 顯示難度選擇頁面
}
}
public function render($view, $data=null, $return=false) {
if ($this->beforeRender($view)) {
$output = $this->renderPartial($view, $data, true); // 渲染局部視圖
if (($layoutFile = $this->getLayoutFile($this->layout)) !== false) {
$output = $this->renderFile($layoutFile, ['content'=>$output], true); // 套用版面
}
$this->afterRender($view, $output);
$output = $this->processOutput($output); // 處理輸出(如 clientScript)
if ($return) return $output;
else echo $output;
}
}
關鍵步驟:
renderPartial() 載入 views/game/play.php 產生內容片段。getLayoutFile() 取得版面配置檔(預設 views/layouts/main.php)。renderFile() 將片段注入版面配置的 $content 變數。processOutput() 注入 CSS/JS、執行 widget 輸出等。views/
├─ layouts/
│ └─ main.php // 版面配置,含 <?php echo $content; ?>
└─ game/
├─ play.php // 難度選擇頁
└─ guess.php // 猜字遊戲頁
此流程展現 YII 「兩階段渲染」設計:先產生內容視圖,再套用版面配置,職責分離清晰,支援多版面、巢狀 widget、客戶端腳本自動管理。