Action 的概述
InlineAction 就是内联动作,所谓的内联动作就是放到controller 里面的 actionXXX 这种 Action。
customAction 就是独立动作,就是直接继承 Action 并实现 run 方法的 Action。
与 Controller 的交互
public function createAction($id)
{
if ($id === '') {
$id = $this->defaultAction;
} $actionMap = $this->actions();
if (isset($actionMap[$id])) {
return Yii::createObject($actionMap[$id], [$id, $this]);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
$methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id))));
if (method_exists($this, $methodName)) {
$method = new \ReflectionMethod($this, $methodName);
if ($method->isPublic() && $method->getName() === $methodName) {
return new InlineAction($id, $this, $methodName);
}
}
} return null;
}
以上代码出自 yii\base\contoller。
createAction 首先通过 controller 的 actions 判断是否是独立的 Action, 如果是返回对象的实例,然后执行 runWithParams, 然后在执行 run 方法。这就是为什么独立的Action 都有实现 run 方法。下面是代码(yii\base\Action)
public function runWithParams($params)
{
if (!method_exists($this, 'run')) {
throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
}
$args = $this->controller->bindActionParams($this, $params);
Yii::trace('Running action: ' . get_class($this) . '::run()', __METHOD__);
if (Yii::$app->requestedParams === null) {
Yii::$app->requestedParams = $args;
}
if ($this->beforeRun()) {
$result = call_user_func_array([$this, 'run'], $args);
$this->afterRun(); return $result;
} else {
return null;
}
}
如果不是独立的Action, 就会返回 InlineAction,它重写了runWithParams方法
public function runWithParams($params)
{
$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;
} return call_user_func_array([$this->controller, $this->actionMethod], $args);
}
总结
一开始看源码的时候,从 index.php 一直往下跟,结果看到Action的时候,有点乱了,$this 不知道指到什么地方去了,懵圈了。后来从 yii\base 开始看才看明白。欢迎讨论