Maison > Article > développement back-end > yii2源码学习笔记(八),yii2源码学习笔记_PHP教程
Action是所有控制器的基类,接下来了解一下它的源码。yii2\base\Action.php
<span> 1</span> <?<span>php </span><span> 2</span> <span>/*</span><span>* </span><span> 3</span> <span> * @link </span><span>http://www.yiiframework.com/</span> <span> 4</span> <span> * @copyright Copyright (c) 2008 Yii Software LLC </span><span> 5</span> <span> * @license </span><span>http://www.yiiframework.com/license/</span> <span> 6</span> <span>*/</span> <span> 7</span> <span> 8</span> <span>namespace</span> yii\<span>base</span><span>; </span><span> 9</span> <span> 10</span> <span>use Yii; </span><span> 11</span> <span> 12</span> <span>/*</span><span>* </span><span> 13</span> <span> * Action is the base class for all controller action classes. </span><span> 14</span> <span> * 是所有控制器的基类 </span><span> 15</span> <span> * Action provides a way to divide a complex controller into </span><span> 16</span> <span> * smaller actions in separate class files. </span><span> 17</span> <span> * 控制器提供了一种重复使用操作方法的代码,在多个控制器或不同的项目中使用 </span><span> 18</span> <span> * Derived classes must implement a method named `run()`. This method </span><span> 19</span> <span> * will be invoked by the controller when the action is requested. </span><span> 20</span> <span> * The `run()` method can have parameters which will be filled up </span><span> 21</span> <span> * with user input values automatically according to their names. </span><span> 22</span> <span> * 派生类必须实现一个名为run()的方法,这个方法会在控制器被请求时调用。 </span><span> 23</span> <span> * 它可以有参数,将用户输入值的根据他们的名字自动填补。 </span><span> 24</span> <span> * For example, if the `run()` method is declared as follows: </span><span> 25</span> <span> * 例:run()方法调用声明如下: </span><span> 26</span> <span> * ~~~ </span><span> 27</span> <span> * public function run($id, $type = 'book') { ... } </span><span> 28</span> <span> * ~~~ </span><span> 29</span> <span> * </span><span> 30</span> <span> * And the parameters provided for the action are: `['id' => 1]`. </span><span> 31</span> <span> * Then the `run()` method will be invoked as `run(1)` automatically. </span><span> 32</span> <span> * 并且提供了操作的参数 ['id'=>1]; </span><span> 33</span> <span> * 当run(1)时自动调用run(); </span><span> 34</span> <span> * @property string $uniqueId The unique ID of this action among the whole application. This property is </span><span> 35</span> <span> * read-only. </span><span> 36</span> <span> * 整个应用程序中,这一行动的唯一标识。此属性是只读 </span><span> 37</span> <span> * @author Qiang Xue <qiang.xue@gmail.com> </span><span> 38</span> <span> * @since 2.0 </span><span> 39</span> <span>*/</span> <span> 40</span> <span>class</span><span> Action extends Component </span><span> 41</span> <span>{ </span><span> 42</span> <span>/*</span><span>* </span><span> 43</span> <span> * @var string ID of the action ID的动作 </span><span> 44</span> <span>*/</span> <span> 45</span> <span>public</span><span> $id; </span><span> 46</span> <span>/*</span><span>* </span><span> 47</span> <span> * @var Controller|\yii\web\Controller the controller that owns this action </span><span> 48</span> <span> * 拥有这一行动的控制器 </span><span> 49</span> <span>*/</span> <span> 50</span> <span>public</span><span> $controller; </span><span> 51</span> <span> 52</span> <span> 53</span> <span>/*</span><span>* </span><span> 54</span> <span> * Constructor. </span><span> 55</span> <span> * 构造函数 </span><span> 56</span> <span> * @param string $id the ID of this action 这一行动的ID </span><span> 57</span> <span> * @param Controller $controller the controller that owns this action 拥有这一行动的控制器 </span><span> 58</span> <span> * @param array $config name-value pairs that will be used to initialize the object properties </span><span> 59</span> <span> * 用来初始化对象属性的 name-value </span><span> 60</span> <span>*/</span> <span> 61</span> <span>public</span> function __construct($id, $controller, $config =<span> []) </span><span> 62</span> <span> { </span><span> 63</span> $<span>this</span>->id =<span> $id; </span><span> 64</span> $<span>this</span>->controller =<span> $controller; </span><span> 65</span> <span>//</span><span>调用父类的__construct()方法</span> <span> 66</span> <span> parent::__construct($config); </span><span> 67</span> <span> } </span><span> 68</span> <span> 69</span> <span>/*</span><span>* </span><span> 70</span> <span> * Returns the unique ID of this action among the whole application. </span><span> 71</span> <span> * 返回整个应用程序中的唯一ID。 </span><span> 72</span> <span> * @return string the unique ID of this action among the whole application. </span><span> 73</span> <span> * 在整个应用程序中,这一行动的唯一ID。 </span><span> 74</span> <span>*/</span> <span> 75</span> <span>public</span><span> function getUniqueId() </span><span> 76</span> <span> { </span><span> 77</span> <span>return</span> $<span>this</span>->controller->getUniqueId() . <span>'</span><span>/</span><span>'</span> . $<span>this</span>-><span>id; </span><span> 78</span> <span> } </span><span> 79</span> <span> 80</span> <span>/*</span><span>* </span><span> 81</span> <span> * Runs this action with the specified parameters. 用指定的参数运行此操作。 </span><span> 82</span> <span> * This method is mainly invoked by the controller. 该方法主要由控制器调用。 </span><span> 83</span> <span> * </span><span> 84</span> <span> * @param array $params the parameters to be bound to the action's run() method.绑定到行动的run()方法的参数。 </span><span> 85</span> <span> * @return mixed the result of the action 行动的结果 命名参数是否有效的 </span><span> 86</span> <span> * @throws InvalidConfigException if the action class does not have a run() method </span><span> 87</span> <span> * 如果动作类没有run()方法 扔出异常 </span><span> 88</span> <span>*/</span> <span> 89</span> <span>public</span> function runWithParams($<span>params</span><span>) </span><span> 90</span> <span> { </span><span> 91</span> <span>if</span> (!method_exists($<span>this</span>, <span>'</span><span>run</span><span>'</span>)) {<span>//</span><span>如果动作类没有run()方法 抛出异常</span> <span> 92</span> <span>throw</span> <span>new</span> InvalidConfigException(get_class($<span>this</span>) . <span>'</span><span> must define a "run()" method.</span><span>'</span><span>); </span><span> 93</span> <span> } </span><span> 94</span> <span>//</span><span>调用bindActionParams()方法将参数绑定到动作。</span> <span> 95</span> $args = $<span>this</span>->controller->bindActionParams($<span>this</span>, $<span>params</span><span>); </span><span> 96</span> <span>//</span><span>记录跟踪消息</span> <span> 97</span> Yii::trace(<span>'</span><span>Running action: </span><span>'</span> . get_class($<span>this</span>) . <span>'</span><span>::run()</span><span>'</span><span>, __METHOD__); </span><span> 98</span> <span>if</span> (Yii::$app->requestedParams === <span>null</span><span>) { </span><span> 99</span> <span>//</span><span>请求的动作提供的参数</span> <span>100</span> Yii::$app->requestedParams =<span> $args; </span><span>101</span> <span> } </span><span>102</span> <span>if</span> ($<span>this</span>-><span>beforeRun()) { </span><span>103</span> <span>//</span><span>执行run()方法</span> <span>104</span> $result = call_user_func_array([$<span>this</span>, <span>'</span><span>run</span><span>'</span><span>], $args); </span><span>105</span> $<span>this</span>-><span>afterRun(); </span><span>106</span> <span>107</span> <span>return</span><span> $result; </span><span>108</span> } <span>else</span><span> { </span><span>109</span> <span>return</span> <span>null</span><span>; </span><span>110</span> <span> } </span><span>111</span> <span> } </span><span>112</span> <span>113</span> <span>/*</span><span>* </span><span>114</span> <span> * This method is called right before `run()` is executed. </span><span>115</span> <span> * ` run() `执行前方法被调用。 </span><span>116</span> <span> * You may override this method to do preparation work for the action run. </span><span>117</span> <span> * 可以重写此方法,为该操作运行的准备工作。 </span><span>118</span> <span> * If the method returns false, it will cancel the action. </span><span>119</span> <span> * 如果该方法返回false,取消该操作。 </span><span>120</span> <span> * @return boolean whether to run the action. </span><span>121</span> <span>*/</span> <span>122</span> <span>protected</span><span> function beforeRun() </span><span>123</span> <span> { </span><span>124</span> <span>return</span> <span>true</span><span>; </span><span>125</span> <span> } </span><span>126</span> <span>127</span> <span>/*</span><span>* </span><span>128</span> <span> * This method is called right after `run()` is executed. ` run() `执行后 方法被调用。 </span><span>129</span> <span> * You may override this method to do post-processing work for the action run. </span><span>130</span> <span> * 可以重写此方法来处理该动作的后续处理工作。 </span><span>131</span> <span>*/</span> <span>132</span> <span>protected</span><span> function afterRun() </span><span>133</span> <span> { </span><span>134</span> <span> } </span><span>135</span> }
接下来我们看一下事件参数相关重要的一个类ActionEvent。yii2\base\ActionEvent.php
<span> 1</span> <?<span>php </span><span> 2</span> <span>/*</span><span>* </span><span> 3</span> <span> * @link </span><span>http://www.yiiframework.com/</span> <span> 4</span> <span> * @copyright Copyright (c) 2008 Yii Software LLC </span><span> 5</span> <span> * @license </span><span>http://www.yiiframework.com/license/</span> <span> 6</span> <span>*/</span> <span> 7</span> <span> 8</span> <span>namespace</span> yii\<span>base</span><span>; </span><span> 9</span> <span>10</span> <span>/*</span><span>* </span><span>11</span> <span> * ActionEvent represents the event parameter used for an action event. </span><span>12</span> <span> * 用于操作事件的事件参数 </span><span>13</span> <span> * By setting the [[isValid]] property, one may control whether to continue running the action. </span><span>14</span> <span> * 通过设置[[isValid]]属性,控制是否继续运行action。 </span><span>15</span> <span> * @author Qiang Xue <qiang.xue@gmail.com> </span><span>16</span> <span> * @since 2.0 </span><span>17</span> <span>*/</span> <span>18</span> <span>class</span><span> ActionEvent extends Event </span><span>19</span> <span>{ </span><span>20</span> <span>/*</span><span>* </span><span>21</span> <span> * @var Action the action currently being executed </span><span>22</span> <span> * 目前正在执行的行动 </span><span>23</span> <span>*/</span> <span>24</span> <span>public</span><span> $action; </span><span>25</span> <span>/*</span><span>* </span><span>26</span> <span> * @var mixed the action result. Event handlers may modify this property to change the action result. </span><span>27</span> <span> * 操作结果 事件处理程序可以修改此属性来更改操作结果。 </span><span>28</span> <span>*/</span> <span>29</span> <span>public</span><span> $result; </span><span>30</span> <span>/*</span><span>* </span><span>31</span> <span> * @var boolean whether to continue running the action. Event handlers of </span><span>32</span> <span> * [[Controller::EVENT_BEFORE_ACTION]] may set this property to decide whether </span><span>33</span> <span> * to continue running the current action. </span><span>34</span> <span> * 是否继续运行该动作。设置[[Controller::EVENT_BEFORE_ACTION]]属性决定是否执行当前的操作 </span><span>35</span> <span>*/</span> <span>36</span> <span>public</span> $isValid = <span>true</span><span>; </span><span>37</span> <span>38</span> <span>39</span> <span>/*</span><span>* </span><span>40</span> <span> * Constructor.构造函数。 </span><span>41</span> <span> * @param Action $action the action associated with this action event.与此事件相关联的动作。 </span><span>42</span> <span> * @param array $config name-value pairs that will be used to initialize the object properties </span><span>43</span> <span> * 用来初始化对象属性的 name-value </span><span>44</span> <span>*/</span> <span>45</span> <span>public</span> function __construct($action, $config =<span> []) </span><span>46</span> <span> { </span><span>47</span> $<span>this</span>->action =<span> $action; </span><span>48</span> <span> parent::__construct($config); </span><span>49</span> <span> } </span><span>50</span> }
今天最后看一下操作过滤器的基类吧ActionFilter。yii2\base\ActionFilter.php。
<span> 1</span> <?<span>php </span><span> 2</span> <span>/*</span><span>* </span><span> 3</span> <span> * @link </span><span>http://www.yiiframework.com/</span> <span> 4</span> <span> * @copyright Copyright (c) 2008 Yii Software LLC </span><span> 5</span> <span> * @license </span><span>http://www.yiiframework.com/license/</span> <span> 6</span> <span>*/</span> <span> 7</span> <span> 8</span> <span>namespace</span> yii\<span>base</span><span>; </span><span> 9</span> <span> 10</span> <span>/*</span><span>* </span><span> 11</span> <span> * ActionFilter is the base class for action filters. </span><span> 12</span> <span> * 是操作过滤器的基类。 </span><span> 13</span> <span> * An action filter will participate in the action execution workflow by responding to </span><span> 14</span> <span> * the `beforeAction` and `afterAction` events triggered by modules and controllers. </span><span> 15</span> <span> * 一个操作过滤器将参与行动的执行工作流程,通过触发模型和控制器的`beforeAction` 和`afterAction` 事件 </span><span> 16</span> <span> * Check implementation of [[\yii\filters\AccessControl]], [[\yii\filters\PageCache]] and [[\yii\filters\HttpCache]] as examples on how to use it. </span><span> 17</span> <span> * </span><span> 18</span> <span> * @author Qiang Xue <qiang.xue@gmail.com> </span><span> 19</span> <span> * @since 2.0 </span><span> 20</span> <span>*/</span> <span> 21</span> <span>class</span><span> ActionFilter extends Behavior </span><span> 22</span> <span>{ </span><span> 23</span> <span>/*</span><span>* </span><span> 24</span> <span> * @var array list of action IDs that this filter should apply to. If this property is not set, </span><span> 25</span> <span> * then the filter applies to all actions, unless they are listed in [[except]]. </span><span> 26</span> <span> * 操作标识列表。如果该属性未设置,过滤器适用于所有的行动,除非它们被列入[[except]]中。 </span><span> 27</span> <span> * If an action ID appears in both [[only]] and [[except]], this filter will NOT apply to it. </span><span> 28</span> <span> * 如果一个操作ID 出现在[[only]] 和[[except]]中,该筛选器将不适用它 </span><span> 29</span> <span> * Note that if the filter is attached to a module, the action IDs should also include child module IDs (if any) </span><span> 30</span> <span> * and controller IDs. </span><span> 31</span> <span> * 如果过滤器是链接到一个模块,操作检测还应包括子模块和控制器 </span><span> 32</span> <span> * </span><span> 33</span> <span> * @see except </span><span> 34</span> <span>*/</span> <span> 35</span> <span>public</span><span> $only; </span><span> 36</span> <span>/*</span><span>* </span><span> 37</span> <span> * @var array list of action IDs that this filter should not apply to. </span><span> 38</span> <span> * 此筛选器不应适用于操作ID。 </span><span> 39</span> <span> * @see only </span><span> 40</span> <span>*/</span> <span> 41</span> <span>public</span> $except =<span> []; </span><span> 42</span> <span> 43</span> <span> 44</span> <span>/*</span><span>* </span><span> 45</span> <span> * @inheritdoc </span><span> 46</span> <span> * 将行为对象附加到组件。 </span><span> 47</span> <span>*/</span> <span> 48</span> <span>public</span><span> function attach($owner) </span><span> 49</span> <span> { </span><span> 50</span> $<span>this</span>->owner =<span> $owner; </span><span> 51</span> $owner->on(Controller::EVENT_BEFORE_ACTION, [$<span>this</span>, <span>'</span><span>beforeFilter</span><span>'</span><span>]); </span><span> 52</span> <span> } </span><span> 53</span> <span> 54</span> <span>/*</span><span>* </span><span> 55</span> <span> * @inheritdoc </span><span> 56</span> <span> * 将行为对象和组件分离。 </span><span> 57</span> <span>*/</span> <span> 58</span> <span>public</span><span> function detach() </span><span> 59</span> <span> { </span><span> 60</span> <span>if</span> ($<span>this</span>-><span>owner) { </span><span> 61</span> $<span>this</span>->owner->off(Controller::EVENT_BEFORE_ACTION, [$<span>this</span>, <span>'</span><span>beforeFilter</span><span>'</span><span>]); </span><span> 62</span> $<span>this</span>->owner->off(Controller::EVENT_AFTER_ACTION, [$<span>this</span>, <span>'</span><span>afterFilter</span><span>'</span><span>]); </span><span> 63</span> $<span>this</span>->owner = <span>null</span><span>; </span><span> 64</span> <span> } </span><span> 65</span> <span> } </span><span> 66</span> <span> 67</span> <span>/*</span><span>* </span><span> 68</span> <span> * @param ActionEvent $event 在动作之前调用 </span><span> 69</span> <span>*/</span> <span> 70</span> <span>public</span> function beforeFilter($<span>event</span><span>) </span><span> 71</span> <span> { </span><span> 72</span> <span>if</span> (!$<span>this</span>->isActive($<span>event</span>-><span>action)) { </span><span> 73</span> <span>return</span><span>; </span><span> 74</span> <span> } </span><span> 75</span> <span> 76</span> $<span>event</span>->isValid = $<span>this</span>->beforeAction($<span>event</span>-><span>action); </span><span> 77</span> <span>if</span> ($<span>event</span>-><span>isValid) { </span><span> 78</span> <span>//</span><span> call afterFilter only if beforeFilter succeeds beforeFilter 执行成功调用afterFilter </span><span> 79</span> <span>//</span><span> beforeFilter and afterFilter should be properly nested 两者要配合应用</span> <span> 80</span> $<span>this</span>->owner->on(Controller::EVENT_AFTER_ACTION, [$<span>this</span>, <span>'</span><span>afterFilter</span><span>'</span>], <span>null</span>, <span>false</span><span>); </span><span> 81</span> } <span>else</span><span> { </span><span> 82</span> $<span>event</span>->handled = <span>true</span><span>; </span><span> 83</span> <span> } </span><span> 84</span> <span> } </span><span> 85</span> <span> 86</span> <span>/*</span><span>* </span><span> 87</span> <span> * @param ActionEvent $event </span><span> 88</span> <span>*/</span> <span> 89</span> <span>public</span> function afterFilter($<span>event</span><span>) </span><span> 90</span> <span> { </span><span> 91</span> $<span>event</span>->result = $<span>this</span>->afterAction($<span>event</span>->action, $<span>event</span>-><span>result); </span><span> 92</span> $<span>this</span>->owner->off(Controller::EVENT_AFTER_ACTION, [$<span>this</span>, <span>'</span><span>afterFilter</span><span>'</span><span>]); </span><span> 93</span> <span> } </span><span> 94</span> <span> 95</span> <span>/*</span><span>* </span><span> 96</span> <span> * This method is invoked right before an action is to be executed (after all possible filters.) </span><span> 97</span> <span> * 此方法是在一个动作之前被调用的( </span><span> 98</span> <span> * You may override this method to do last-minute preparation for the action. </span><span> 99</span> <span> * @param Action $action the action to be executed.要执行的动作 </span><span>100</span> <span> * @return boolean whether the action should continue to be executed. </span><span>101</span> <span> * 是否应继续执行该动作。 </span><span>102</span> <span>*/</span> <span>103</span> <span>public</span><span> function beforeAction($action) </span><span>104</span> <span> { </span><span>105</span> <span>return</span> <span>true</span><span>; </span><span>106</span> <span> } </span><span>107</span> <span>108</span> <span>/*</span><span>* </span><span>109</span> <span> * This method is invoked right after an action is executed. </span><span>110</span> <span> * 此方法是在执行动作之后调用的。 </span><span>111</span> <span> * You may override this method to do some postprocessing for the action. </span><span>112</span> <span> * @param Action $action the action just executed. 刚刚执行的动作 </span><span>113</span> <span> * @param mixed $result the action execution result 行动执行结果 </span><span>114</span> <span> * @return mixed the processed action result. 处理结果。 </span><span>115</span> <span>*/</span> <span>116</span> <span>public</span><span> function afterAction($action, $result) </span><span>117</span> <span> { </span><span>118</span> <span>return</span><span> $result; </span><span>119</span> <span> } </span><span>120</span> <span>121</span> <span>/*</span><span>* </span><span>122</span> <span> * Returns a value indicating whether the filer is active for the given action. </span><span>123</span> <span> * 返回一个值,给定的过滤器的行动是否为是积极的。 </span><span>124</span> <span> * @param Action $action the action being filtered 被过滤的动作 </span><span>125</span> <span> * @return boolean whether the filer is active for the given action. </span><span>126</span> <span> * 给定的过滤器的行动是否为是积极的。 </span><span>127</span> <span>*/</span> <span>128</span> <span>protected</span><span> function isActive($action) </span><span>129</span> <span> { </span><span>130</span> <span>if</span> ($<span>this</span>-><span>owner instanceof Module) { </span><span>131</span> <span>//</span><span> convert action uniqueId into an ID relative to the module</span> <span>132</span> $mid = $<span>this</span>->owner-><span>getUniqueId(); </span><span>133</span> $id = $action-><span>getUniqueId(); </span><span>134</span> <span>if</span> ($mid !== <span>''</span> && strpos($id, $mid) === <span>0</span><span>) { </span><span>135</span> $id = substr($id, strlen($mid) + <span>1</span><span>); </span><span>136</span> <span> } </span><span>137</span> } <span>else</span><span> { </span><span>138</span> $id = $action-><span>id; </span><span>139</span> <span> } </span><span>140</span> <span>return</span> !in_array($id, $<span>this</span>->except, <span>true</span>) && (empty($<span>this</span>->only) || in_array($id, $<span>this</span>->only, <span>true</span><span>)); </span><span>141</span> <span> } </span><span>142</span> }