liuzhang 2018-04-16 14:42:11 5273次浏览 2条评论 0 0 0

Action 的概述

项目中Action 的 UML 类图的关系如下:
未命名文件 (4).png
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 开始看才看明白。欢迎讨论

您需要登录后才可以评论。登录 | 立即注册