http://blog.csdn.net/alex_my/article/details/54142711php
版本web
建立Applicationbootstrap
run過程app
handleRequestyii
runAction函數
簡述流程網站
1 版本this
// yii\BaseYii\getVersion public static function getVersion() { return '2.0.10'; }
2url
// 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__); } } }
整個run過程經歷如下過程:spa
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; } }
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); ... } ... }
建立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返回給客戶端