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 <qiang.xue@gmail.com>
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 <qiang.xue@gmail.com>
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 <qiang.xue@gmail.com>
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 }