首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Yii2 源碼解讀:Controller 基類核心流程與視圖渲染機制

     編輯:PHP 相關知識

Yii2 源碼解讀:Controller 基類核心流程與視圖渲染機制

yii\base\Controller 處理路由解析、動作建立、參數綁定、前後置鉤子、視圖渲染與佈局查找。本文節選關鍵方法原始碼並解析核心邏輯。

路由執行入口 run($route, $params)

public function run($route, $params = []) {
    $pos = strpos($route, '/');
    if ($pos === false) return $this->runAction($route, $params);           // 當前控制器動作
    elseif ($pos > 0) return $this->module->runAction($route, $params);      // 子模組路由
    else return Yii::$app->runAction(ltrim($route, '/'), $params);           // 絕對路由(從應用根)
}

動作建立 createAction($id)

public function createAction($id) {
    if ($id === '') $id = $this->defaultAction;
    $actionMap = $this->actions(); // 覆寫 actions() 回傳獨立 Action 類別配置
    if (isset($actionMap[$id])) return Yii::createObject($actionMap[$id], [$id, $this]);

    // 行為動作:actionXyz 對應方法 actionXyz
    if (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
        $methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id))));
        if (method_exists($this, $methodName)) {
            $method = new \ReflectionMethod($this, $methodName);
            if ($method->isPublic() && $method->getName() === $methodName)
                return new InlineAction($id, $this, $methodName);
        }
    }
    return null;
}

支援獨立 Action 類別與行為動作(方法名)雙模式,命名規則:action-id → actionActionId。

前後置鉤子

public function beforeAction($action) {
    $event = new ActionEvent($action);
    $this->trigger(self::EVENT_BEFORE_ACTION, $event);
    return $event->isValid; // false 可中斷執行
}
public function afterAction($action, $result) {
    $event = new ActionEvent($action);
    $event->result = $result;
    $this->trigger(self::EVENT_AFTER_ACTION, $event);
    return $event->result;
}

視圖渲染核心 render() / renderContent() / renderPartial() / renderFile()

public function render($view, $params = []) {
    $content = $this->getView()->render($view, $params, $this); // 渲染視圖檔
    return $this->renderContent($content);                      // 套用佈局
}
public function renderContent($content) {
    $layoutFile = $this->findLayoutFile($this->getView());
    return $layoutFile !== false
        ? $this->getView()->renderFile($layoutFile, ['content' => $content], $this)
        : $content;
}
public function renderPartial($view, $params = []) {
    return $this->getView()->render($view, $params, $this); // 不套用佈局
}
public function renderFile($file, $params = []) {
    return $this->getView()->renderFile($file, $params, $this);
}

佈局檔查找 findLayoutFile($view)

  1. 若 $this->layout 為字串 → 直接使用。
  2. 若 null → 向上遞歸查找父模組 layout 非空者。
  3. 路徑解析規則:
    • @alias → Yii::getAlias()
    • /path → 應用 layoutPath
    • relative → 當前模組 layoutPath
  4. 補全副檔名:優先 view->defaultExtension,回退 .php。

視圖物件存取

public function getView() {
    return $this->_view ?? ($this->_view = Yii::$app->getView());
}

模組層級存取 getModules() / getUniqueId() / getRoute()

public function getModules() {
    $modules = [$this->module];
    $module = $this->module;
    while ($module->module !== null) {
        array_unshift($modules, $module->module);
        $module = $module->module;
    }
    return $modules;
}
public function getUniqueId() {
    return $this->module instanceof Application ? $this->id : $this->module->getUniqueId() . '/' . $this->id;
}
public function getRoute() {
    return $this->action ? $this->action->getUniqueId() : $this->getUniqueId();
}

總結

Controller 基類將「路由→動作建立→參數綁定→前置鉤子→執行→後置鉤子→視圖渲染→佈局套用」完整串聯,並提供靈活的覆寫點(actions()、beforeAction()、findLayoutFile()),是 Yii2 請求處理管線的核心樞紐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved