yii2源码学习笔记(八),yii2源码学习笔记
程序员文章站
2022-06-12 20:07:34
...
yii2源码学习笔记(八),yii2源码学习笔记
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 Xue38 * @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 Xue16 * @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 Xue19 * @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 }