Action是所有控制器的基類,接下來了解一下它的源碼。yii2\base\Action.php
1 <?php 2 /** 3 * @link http://www.yiiframework.com/ 4 * @copyright Copyright (c) 2008 Yii Software LLC 5 * @license http://www.yiiframework.com/license/ 6 */ 7 8 namespace yii\base; 9 10 use Yii; 11 12 /** 13 * Action is the base class for all controller action classes. 14 * 是所有控制器的基類 15 * Action provides a way to divide a complex controller into 16 * smaller actions in separate class files. 17 * 控制器提供了一種重復使用操作方法的代碼,在多個控制器或不同的項目中使用 18 * Derived classes must implement a method named `run()`. This method 19 * will be invoked by the controller when the action is requested. 20 * The `run()` method can have parameters which will be filled up 21 * with user input values automatically according to their names. 22 * 派生類必須實現一個名為run()的方法,這個方法會在控制器被請求時調用。 23 * 它可以有參數,將用戶輸入值的根據他們的名字自動填補。 24 * For example, if the `run()` method is declared as follows: 25 * 例:run()方法調用聲明如下: 26 * ~~~ 27 * public function run($id, $type = 'book') { ... } 28 * ~~~ 29 * 30 * And the parameters provided for the action are: `['id' => 1]`. 31 * Then the `run()` method will be invoked as `run(1)` automatically. 32 * 並且提供了操作的參數 ['id'=>1]; 33 * 當run(1)時自動調用run(); 34 * @property string $uniqueId The unique ID of this action among the whole application. This property is 35 * read-only. 36 * 整個應用程序中,這一行動的唯一標識。此屬性是只讀 37 * @author Qiang Xue <[email protected]> 38 * @since 2.0 39 */ 40 class Action extends Component 41 { 42 /** 43 * @var string ID of the action ID的動作 44 */ 45 public $id; 46 /** 47 * @var Controller|\yii\web\Controller the controller that owns this action 48 * 擁有這一行動的控制器 49 */ 50 public $controller; 51 52 53 /** 54 * Constructor. 55 * 構造函數 56 * @param string $id the ID of this action 這一行動的ID 57 * @param Controller $controller the controller that owns this action 擁有這一行動的控制器 58 * @param array $config name-value pairs that will be used to initialize the object properties 59 * 用來初始化對象屬性的 name-value 60 */ 61 public function __construct($id, $controller, $config = []) 62 { 63 $this->id = $id; 64 $this->controller = $controller; 65 //調用父類的__construct()方法 66 parent::__construct($config); 67 } 68 69 /** 70 * Returns the unique ID of this action among the whole application. 71 * 返回整個應用程序中的唯一ID。 72 * @return string the unique ID of this action among the whole application. 73 * 在整個應用程序中,這一行動的唯一ID。 74 */ 75 public function getUniqueId() 76 { 77 return $this->controller->getUniqueId() . '/' . $this->id; 78 } 79 80 /** 81 * Runs this action with the specified parameters. 用指定的參數運行此操作。 82 * This method is mainly invoked by the controller. 該方法主要由控制器調用。 83 * 84 * @param array $params the parameters to be bound to the action's run() method.綁定到行動的run()方法的參數。 85 * @return mixed the result of the action 行動的結果 命名參數是否有效的 86 * @throws InvalidConfigException if the action class does not have a run() method 87 * 如果動作類沒有run()方法 扔出異常 88 */ 89 public function runWithParams($params) 90 { 91 if (!method_exists($this, 'run')) {//如果動作類沒有run()方法 拋出異常 92 throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.'); 93 } 94 //調用bindActionParams()方法將參數綁定到動作。 95 $args = $this->controller->bindActionParams($this, $params); 96 //記錄跟蹤消息 97 Yii::trace('Running action: ' . get_class($this) . '::run()', __METHOD__); 98 if (Yii::$app->requestedParams === null) { 99 //請求的動作提供的參數 100 Yii::$app->requestedParams = $args; 101 } 102 if ($this->beforeRun()) { 103 //執行run()方法 104 $result = call_user_func_array([$this, 'run'], $args); 105 $this->afterRun(); 106 107 return $result; 108 } else { 109 return null; 110 } 111 } 112 113 /** 114 * This method is called right before `run()` is executed. 115 * ` run() `執行前方法被調用。 116 * You may override this method to do preparation work for the action run. 117 * 可以重寫此方法,為該操作運行的准備工作。 118 * If the method returns false, it will cancel the action. 119 * 如果該方法返回false,取消該操作。 120 * @return boolean whether to run the action. 121 */ 122 protected function beforeRun() 123 { 124 return true; 125 } 126 127 /** 128 * This method is called right after `run()` is executed. ` run() `執行後 方法被調用。 129 * You may override this method to do post-processing work for the action run. 130 * 可以重寫此方法來處理該動作的後續處理工作。 131 */ 132 protected function afterRun() 133 { 134 } 135 }
接下來我們看一下事件參數相關重要的一個類ActionEvent。yii2\base\ActionEvent.php
1 <?php 2 /** 3 * @link http://www.yiiframework.com/ 4 * @copyright Copyright (c) 2008 Yii Software LLC 5 * @license http://www.yiiframework.com/license/ 6 */ 7 8 namespace yii\base; 9 10 /** 11 * ActionEvent represents the event parameter used for an action event. 12 * 用於操作事件的事件參數 13 * By setting the [[isValid]] property, one may control whether to continue running the action. 14 * 通過設置[[isValid]]屬性,控制是否繼續運行action。 15 * @author Qiang Xue <[email protected]> 16 * @since 2.0 17 */ 18 class ActionEvent extends Event 19 { 20 /** 21 * @var Action the action currently being executed 22 * 目前正在執行的行動 23 */ 24 public $action; 25 /** 26 * @var mixed the action result. Event handlers may modify this property to change the action result. 27 * 操作結果 事件處理程序可以修改此屬性來更改操作結果。 28 */ 29 public $result; 30 /** 31 * @var boolean whether to continue running the action. Event handlers of 32 * [[Controller::EVENT_BEFORE_ACTION]] may set this property to decide whether 33 * to continue running the current action. 34 * 是否繼續運行該動作。設置[[Controller::EVENT_BEFORE_ACTION]]屬性決定是否執行當前的操作 35 */ 36 public $isValid = true; 37 38 39 /** 40 * Constructor.構造函數。 41 * @param Action $action the action associated with this action event.與此事件相關聯的動作。 42 * @param array $config name-value pairs that will be used to initialize the object properties 43 * 用來初始化對象屬性的 name-value 44 */ 45 public function __construct($action, $config = []) 46 { 47 $this->action = $action; 48 parent::__construct($config); 49 } 50 }
今天最後看一下操作過濾器的基類吧ActionFilter。yii2\base\ActionFilter.php。
1 <?php 2 /** 3 * @link http://www.yiiframework.com/ 4 * @copyright Copyright (c) 2008 Yii Software LLC 5 * @license http://www.yiiframework.com/license/ 6 */ 7 8 namespace yii\base; 9 10 /** 11 * ActionFilter is the base class for action filters. 12 * 是操作過濾器的基類。 13 * An action filter will participate in the action execution workflow by responding to 14 * the `beforeAction` and `afterAction` events triggered by modules and controllers. 15 * 一個操作過濾器將參與行動的執行工作流程,通過觸發模型和控制器的`beforeAction` 和`afterAction` 事件 16 * Check implementation of [[\yii\filters\AccessControl]], [[\yii\filters\PageCache]] and [[\yii\filters\HttpCache]] as examples on how to use it. 17 * 18 * @author Qiang Xue <[email protected]> 19 * @since 2.0 20 */ 21 class ActionFilter extends Behavior 22 { 23 /** 24 * @var array list of action IDs that this filter should apply to. If this property is not set, 25 * then the filter applies to all actions, unless they are listed in [[except]]. 26 * 操作標識列表。如果該屬性未設置,過濾器適用於所有的行動,除非它們被列入[[except]]中。 27 * If an action ID appears in both [[only]] and [[except]], this filter will NOT apply to it. 28 * 如果一個操作ID 出現在[[only]] 和[[except]]中,該篩選器將不適用它 29 * Note that if the filter is attached to a module, the action IDs should also include child module IDs (if any) 30 * and controller IDs. 31 * 如果過濾器是鏈接到一個模塊,操作檢測還應包括子模塊和控制器 32 * 33 * @see except 34 */ 35 public $only; 36 /** 37 * @var array list of action IDs that this filter should not apply to. 38 * 此篩選器不應適用於操作ID。 39 * @see only 40 */ 41 public $except = []; 42 43 44 /** 45 * @inheritdoc 46 * 將行為對象附加到組件。 47 */ 48 public function attach($owner) 49 { 50 $this->owner = $owner; 51 $owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']); 52 } 53 54 /** 55 * @inheritdoc 56 * 將行為對象和組件分離。 57 */ 58 public function detach() 59 { 60 if ($this->owner) { 61 $this->owner->off(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']); 62 $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']); 63 $this->owner = null; 64 } 65 } 66 67 /** 68 * @param ActionEvent $event 在動作之前調用 69 */ 70 public function beforeFilter($event) 71 { 72 if (!$this->isActive($event->action)) { 73 return; 74 } 75 76 $event->isValid = $this->beforeAction($event->action); 77 if ($event->isValid) { 78 // call afterFilter only if beforeFilter succeeds beforeFilter 執行成功調用afterFilter 79 // beforeFilter and afterFilter should be properly nested 兩者要配合應用 80 $this->owner->on(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter'], null, false); 81 } else { 82 $event->handled = true; 83 } 84 } 85 86 /** 87 * @param ActionEvent $event 88 */ 89 public function afterFilter($event) 90 { 91 $event->result = $this->afterAction($event->action, $event->result); 92 $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']); 93 } 94 95 /** 96 * This method is invoked right before an action is to be executed (after all possible filters.) 97 * 此方法是在一個動作之前被調用的( 98 * You may override this method to do last-minute preparation for the action. 99 * @param Action $action the action to be executed.要執行的動作 100 * @return boolean whether the action should continue to be executed. 101 * 是否應繼續執行該動作。 102 */ 103 public function beforeAction($action) 104 { 105 return true; 106 } 107 108 /** 109 * This method is invoked right after an action is executed. 110 * 此方法是在執行動作之後調用的。 111 * You may override this method to do some postprocessing for the action. 112 * @param Action $action the action just executed. 剛剛執行的動作 113 * @param mixed $result the action execution result 行動執行結果 114 * @return mixed the processed action result. 處理結果。 115 */ 116 public function afterAction($action, $result) 117 { 118 return $result; 119 } 120 121 /** 122 * Returns a value indicating whether the filer is active for the given action. 123 * 返回一個值,給定的過濾器的行動是否為是積極的。 124 * @param Action $action the action being filtered 被過濾的動作 125 * @return boolean whether the filer is active for the given action. 126 * 給定的過濾器的行動是否為是積極的。 127 */ 128 protected function isActive($action) 129 { 130 if ($this->owner instanceof Module) { 131 // convert action uniqueId into an ID relative to the module 132 $mid = $this->owner->getUniqueId(); 133 $id = $action->getUniqueId(); 134 if ($mid !== '' && strpos($id, $mid) === 0) { 135 $id = substr($id, strlen($mid) + 1); 136 } 137 } else { 138 $id = $action->id; 139 } 140 return !in_array($id, $this->except, true) && (empty($this->only) || in_array($id, $this->only, true)); 141 } 142 }