一、runAction方法,根据指定的路由运行控制器操作
/**
* 根据路由运行指定的控制器操作
*/
public function runAction($route, $params = [])
{
$parts = $this->createController($route);
if (is_array($parts)) {
/* @var $controller Controller */
list($controller, $actionID) = $parts;
$oldController = Yii::$app->controller;
Yii::$app->controller = $controller;
$result = $controller->runAction($actionID, $params);
if ($oldController !== null) {
Yii::$app->controller = $oldController;
}
return $result;
}
$id = $this->getUniqueId();
throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');
}
二、createController方法,根据路由创建控制器实例
/**
* 根据路由创建控制器实例
*/
public function createController($route)
{
if ($route === '') {
$route = $this->defaultRoute;
}
// 去除前后的 '/'
$route = trim($route, '/');
if (strpos($route, '//') !== false) {
return false;
}
if (strpos($route, '/') !== false) {
list($id, $route) = explode('/', $route, 2);
} else {
$id = $route;
$route = '';
}
// 1.控制器映射优先
if (isset($this->controllerMap[$id])) {
$controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);
return [$controller, $route];
}
// 2.模块
$module = $this->getModule($id);
if ($module !== null) {
return $module->createController($route);
}
if (($pos = strrpos($route, '/')) !== false) {
$id .= '/' . substr($route, 0, $pos);
$route = substr($route, $pos + 1);
}
$controller = $this->createControllerByID($id);
if ($controller === null && $route !== '') {
$controller = $this->createControllerByID($id . '/' . $route);
$route = '';
}
return $controller === null ? false : [$controller, $route];
}
三、createControllerById方法,根据id创建控制器实例
/**
* 根据id创建控制器实例
*/
public function createControllerByID($id)
{
$pos = strrpos($id, '/');
if ($pos === false) {
$prefix = '';
$className = $id;
} else {
$prefix = substr($id, 0, $pos + 1);
$className = substr($id, $pos + 1);
}
if ($this->isIncorrectClassNameOrPrefix($className, $prefix)) {
return null;
}
$className = preg_replace_callback('%-([a-z0-9_])%i', function ($matches) {
return ucfirst($matches[1]);
}, ucfirst($className)) . 'Controller';
$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');
if (strpos($className, '-') !== false || !class_exists($className)) {
return null;
}
if (is_subclass_of($className, 'yii\base\Controller')) {
$controller = Yii::createObject($className, [$id, $this]);
return get_class($controller) === $className ? $controller : null;
} elseif (YII_DEBUG) {
throw new InvalidConfigException('Controller class must extend from \\yii\\base\\Controller.');
}
return null;
}
四、isIncorrectClassNameOrPrefix方法,检查类或前缀是否符合规则
/**
* 检查类或者前缀是否正确
*/
private function isIncorrectClassNameOrPrefix($className, $prefix)
{
if (!preg_match('%^[a-z][a-z0-9\\-_]*$%', $className)) {
return true;
}
if ($prefix !== '' && !preg_match('%^[a-z0-9_/]+$%i', $prefix)) {
return true;
}
return false;
}
五、beforeAction方法,操作执行前事件
/**
* 模块$action执行前调用
*/
public function beforeAction($action)
{
$event = new ActionEvent($action);
$this->trigger(self::EVENT_BEFORE_ACTION, $event);
return $event->isValid;
}
六、afterAction方法,操作执行后事件
/**
* 模块$action执行后调用
*/
public function afterAction($action, $result)
{
$event = new ActionEvent($action);
$event->result = $result;
$this->trigger(self::EVENT_AFTER_ACTION, $event);
return $event->result;
}
七、get方法,返回指定组件
//返回指定组件
public function get($id, $throwException = true)
{
if (!isset($this->module)) {
return parent::get($id, $throwException);
}
$component = parent::get($id, false);
if ($component === null) {
$component = $this->module->get($id, $throwException);
}
return $component;
}
八、has方法,检查是否存在指定组件
//检查是否存在指定组件
public function has($id, $checkInstance = false)
{
return parent::has($id, $checkInstance) ||
(isset($this->module) && $this->module->has($id, $checkInstance));
}
总结:
阅读了8个方法:
- runAction方法,根据指定的路由运行控制器操作
- createController方法,根据路由创建控制器实例
- createControllerById方法,根据id创建控制器实例
- isIncorrectClassNameOrPrefix方法,检查类或前缀是否符合规则
- beforeAction方法,操作执行前事件
- afterAction方法,操作执行后事件
- get方法,返回指定组件
- has方法,检查是否存在指定组件