標籤:
yii\base\InlineAction
追蹤一個命令列請求的過程
namespace yii\base;use Yii;/** * InlineAction表示一個動作被定義為一個控制器的方法. * * The name of the controller method is available via [[actionMethod]] which * is set by the [[controller]] who creates this action. * * @author Qiang Xue <[email protected]> * @since 2.0 */class InlineAction extends Action{ /** * @var string the controller method that this inline action is associated with */ public $actionMethod; /** * @param string $id the ID of this action * @param Controller $controller the controller that owns this action * @param string $actionMethod the controller method that this inline action is associated with * @param array $config name-value pairs that will be used to initialize the object properties */ public function __construct($id, $controller, $actionMethod, $config = []) { // 傳入action的id,controller的執行個體,action方法的名稱以及action的配置 $this->actionMethod = $actionMethod; parent::__construct($id, $controller, $config); } /** * 這個動作用指定的參數運行. * 這種方法主要是由控制器調用. * @param array $params action parameters * @return mixed the result of the action */ public function runWithParams($params) { // 擷取action的參數,通過合并出入的參數和預設參數得出 $args = $this->controller->bindActionParams($this, $params); Yii::trace(‘Running action: ‘ . get_class($this->controller) . ‘::‘ . $this->actionMethod . ‘()‘, __METHOD__); if (Yii::$app->requestedParams === null) { // 記錄請求的參數 Yii::$app->requestedParams = $args; } // 執行controller的這個action方法 return call_user_func_array([$this->controller, $this->actionMethod], $args); }}
控制器調用
public function __construct($id, $module, $config = []) {+ // 傳入controller的id和所在的module的執行個體 $this->id = $id; $this->module = $module; parent::__construct($config); @@ -117,6 +118,7 @@ public function actions() */ public function runAction($id, $params = []) {+ // 建立action的執行個體 $action = $this->createAction($id); if ($action === null) { throw new InvalidRouteException(‘Unable to resolve the request: ‘ . $this->getUniqueId() . ‘/‘ . $id); @@ -125,6 +127,7 @@ public function runAction($id, $params = []) Yii::trace("Route to run: " . $action->getUniqueId(), __METHOD__); if (Yii::$app->requestedAction === null) {+ // 記錄當前的action為requestedAction Yii::$app->requestedAction = $action; } @@ -135,24 +138,31 @@ public function runAction($id, $params = []) $runAction = true; // call beforeAction on modules+ // 從外到裡一層層執行module的beforeAction foreach ($this->getModules() as $module) { if ($module->beforeAction($action)) {+ // 將執行成功的module放入到$modules中,順序會顛倒 array_unshift($modules, $module); } else {+ // 執行失敗,就標記一下,並跳出迴圈 $runAction = false; break; } } $result = null; + // modules的beforeAction執行成功而且controller本身的beforeAction也執行成功 if ($runAction && $this->beforeAction($action)) { // run the action+ // 執行action $result = $action->runWithParams($params); + // 執行controller本身的afterAction $result = $this->afterAction($action, $result); // call afterAction on modules+ // 從裡到外一層層執行所有modules的beforeAction foreach ($modules as $module) { /* @var $module Module */ $result = $module->afterAction($action, $result); @@ -211,17 +221,25 @@ public function bindActionParams($action, $params) public function createAction($id) { if ($id === ‘‘) {+ // 如果action的id為空白,就是用預設的action $id = $this->defaultAction; } + // 擷取actions方法中的定義的actionMap $actionMap = $this->actions(); if (isset($actionMap[$id])) {+ // 如果action的id在actionMap中,就去建立這個action return Yii::createObject($actionMap[$id], [$id, $this]); } elseif (preg_match(‘/^[a-z0-9\\-_]+$/‘, $id) && strpos($id, ‘--‘) === false && trim($id, ‘-‘) === $id) {+ // 如果id符合命名規範,並且不存在--,而且兩邊不存在-+ // 必須是數字/小寫字母/右斜線/中劃線/底線組成的的+ // 用與拼接controller類名類似的方法拼接action方法的名稱 $methodName = ‘action‘ . str_replace(‘ ‘, ‘‘, ucwords(implode(‘ ‘, explode(‘-‘, $id)))); if (method_exists($this, $methodName)) {+ // 如果方法存在,就new一個ReflectionMethod執行個體 $method = new \ReflectionMethod($this, $methodName); if ($method->isPublic() && $method->getName() === $methodName) {+ // 如果方法是public的,就new一個InlineAction返回 return new InlineAction($id, $this, $methodName); } } @@ -297,9 +315,13 @@ public function afterAction($action, $result) */ public function getModules() {+ // 用當前controller的module組成modules的數組 $modules = [$this->module]; $module = $this->module;+ // 遍曆module的module,直到為空白 while ($module->module !== null) {+ // array_unshift — 在數組開頭插入一個或多個單元+ // 將外面的module插入到modules數組的開頭 array_unshift($modules, $module->module); $module = $module->module; }
學習yii2.0架構閱讀代碼(十六)