http://blog.csdn.net/alex_my/article/details/54142711
版本
创建Application
run过程
handleRequest
runAction
简述流程
1 版本
// yii\BaseYii\getVersion public static function getVersion() { return '2.0.10'; }
2
// web/index.php new yii\web\Application($config)
// yii\base\Application.php public function __construct($config = []) { Yii::$app = $this; static::setInstance($this); $this->state = self::STATE_BEGIN; // 配置属性 $this->preInit($config); // 注册error相关处理函数 $this->registerErrorHandler($config); // 在基类的构造函数中将会调用init()函数 // 在init()中直接调用bootstrap()函数 // 先调用 web/Application::bootstrap() // 再调用 base/Application::bootstrap() Component::__construct($config); }
// base/Application::bootstrap() protected function bootstrap() { // 加载扩展清单中的文件, 默认使用 vendor/yiisoft/extensions.php if ($this->extensions === null) { $file = Yii::getAlias('@vendor/yiisoft/extensions.php'); $this->extensions = is_file($file) ? include($file) : []; } // 创建这些扩展组件 // 如果这些组件实现了BootstrapInterface, 还会调用组件下的bootstrap函数 foreach ($this->extensions as $extension) { if (!empty($extension['alias'])) { foreach ($extension['alias'] as $name => $path) { Yii::setAlias($name, $path); } } if (isset($extension['bootstrap'])) { $component = Yii::createObject($extension['bootstrap']); if ($component instanceof BootstrapInterface) { Yii::trace('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__); $component->bootstrap($this); } else { Yii::trace('Bootstrap with ' . get_class($component), __METHOD__); } } } // 加载将要运行的一些组件, 这些组件配置在main.php, main-local.php中 // 'bootstrap' => ['log'], // $config['bootstrap'][] = 'debug'; // $config['bootstrap'][] = 'gii'; // 开发模式下,默认加载3个: log, debug, gii // 从$config中的配置信息变成base\Application中的属性$bootstrap经历以下步骤: // Component::__construct --> Yii::configure($this, $config) foreach ($this->bootstrap as $class) { $component = null; if (is_string($class)) { if ($this->has($class)) { $component = $this->get($class); } elseif ($this->hasModule($class)) { $component = $this->getModule($class); } elseif (strpos($class, '\\') === false) { throw new InvalidConfigException("Unknown bootstrapping component ID: $class"); } } if (!isset($component)) { $component = Yii::createObject($class); } // 如果这些组件实现了BootstrapInterface, 还会调用组件下的bootstrap函数 if ($component instanceof BootstrapInterface) { Yii::trace('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__); $component->bootstrap($this); } else { Yii::trace('Bootstrap with ' . get_class($component), __METHOD__); } } }
3 run过程
整个run过程经历以下过程:
public function run() { try { // 处理请求前 $this->state = self::STATE_BEFORE_REQUEST; $this->trigger(self::EVENT_BEFORE_REQUEST); // 处理请求 $this->state = self::STATE_HANDLING_REQUEST; $response = $this->handleRequest($this->getRequest()); // 处理请求前 $this->state = self::STATE_AFTER_REQUEST; $this->trigger(self::EVENT_AFTER_REQUEST); // 发送相应给客户端 $this->state = self::STATE_SENDING_RESPONSE; $response->send(); $this->state = self::STATE_END; return $response->exitStatus; } catch (ExitException $e) { $this->end($e->statusCode, isset($response) ? $response : null); return $e->statusCode; } }
4 handleRequest
public function handleRequest($request) { // 如果设置了catchAll变量, 那么所有请求都会跳转到这里 // 示例: // 假设网站维护, 不希望有人访问到内容 // 可以创建一个OfflineController控制器, 对应的views/offline/index.php可以写上 // <h1>网站正在维护中</h1> // 然后在main.php中的$config中添加以下内容 // 'catchAll' => [ 'offline/index'] // 这样, 所有的访问都跳转到 网站正在维护中 的页面了 if (empty($this->catchAll)) { try { list ($route, $params) = $request->resolve(); } catch (UrlNormalizerRedirectException $e) { $url = $e->url; if (is_array($url)) { if (isset($url[0])) { // ensure the route is absolute $url[0] = '/' . ltrim($url[0], '/'); } $url += $request->getQueryParams(); } return $this->getResponse()->redirect(Url::to($url, $e->scheme), $e->statusCode); } } // 跳转到catchAll指定的route else { $route = $this->catchAll[0]; $params = $this->catchAll; unset($params[0]); } try { Yii::trace("Route requested: '$route'", __METHOD__); $this->requestedRoute = $route; $result = $this->runAction($route, $params); ... } ... }
5 runAction
创建Controller,并执行Controller对应的action
public function runAction($route, $params = []) { // 创建Controller $parts = $this->createController($route); if (is_array($parts)) { list($controller, $actionID) = $parts; $oldController = Yii::$app->controller; Yii::$app->controller = $controller; // 执行controller中的action $result = $controller->runAction($actionID, $params); if ($oldController !== null) { Yii::$app->controller = $oldController; } return $result; } else { $id = $this->getUniqueId(); throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".'); } }
6 简述流程 通过Application创建app, 并且读入config, 装载扩展和组件 通过request解析被请求的路由 app根据路由创建controller controller创建action 如果过滤器通过, 则会执行action action会渲染视图view view中的内容一般来自于model 渲染的结果通过response返回给客户端