The content of this article
Starting from the request entry file, the process of sending the response component to the user browser is briefly analyzed.
Process analysis
From the entry document, look directly at the key points and analyze the startup process of application.
$config = require __DIR__.'/../config/web.php'; (new yii\web\Application($config))->run();
First enter the yii web application class
There is no constructor, that is, the parent class yii base Application is found.
public function __construct($config = []) { // Save the currently started application instance and hand it to Yii::$app Yii::$app = $this; static::setInstance($this); $this->state = self::STATE_BEGIN; $this->preInit($config); // Load exception handling, which is deeper, and expand later. $this->registerErrorHandler($config); Component::__construct($config); }
Let's take a look at static::setInstance($this); point to yii base Module
public static function setInstance($instance) { // Add the current instance to the Yii:: $app - > loaded Modules ['yii web Application'] array if ($instance === null) { unset(Yii::$app->loadedModules[get_called_class()]); } else { Yii::$app->loadedModules[get_class($instance)] = $instance; } }
This is mainly used later, such as module, to get App objects through self::getInstance(), similar to Yii::$app. (Can go further later)
Next, look at $this - > preInit ($config);
Here is the framework information for loading configuration files, such as setting aliases, setting framework paths, and so on. The most important thing is to load default components.
foreach ($this->coreComponents() as $id => $component) { if (!isset($config['components'][$id])) { $config['components'][$id] = $component; } elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) { $config['components'][$id]['class'] = $component['class']; } }
Next comes Component:: _construct ($config);
public function __construct($config = []) { if (!empty($config)) { Yii::configure($this, $config);//Localize all configuration information in the configuration file } $this->init(); // Remove the controller's namespace (path) }
So far, the first part has been executed and the execution of $application - > run ()
public function run() { try { $this->state = self::STATE_BEFORE_REQUEST; //Loading event functions. Similar to a dog, I'll go into it later. $this->trigger(self::EVENT_BEFORE_REQUEST); $this->state = self::STATE_HANDLING_REQUEST; // Top priority - loading controller $response = $this->handleRequest($this->getRequest()); $this->state = self::STATE_AFTER_REQUEST; $this->trigger(self::EVENT_AFTER_REQUEST);//Loading event function $this->state = self::STATE_SENDING_RESPONSE; $response->send();//Output page content $this->state = self::STATE_END; return $response->exitStatus; } catch (ExitException $e) { $this->end($e->statusCode, isset($response) ? $response : null); return $e->statusCode; } }
Let's look at $response = $this - > handleRequest ($this - > getRequest ()).
public function handleRequest($request) { 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); } } else { $route = $this->catchAll[0]; $params = $this->catchAll; unset($params[0]); } try { Yii::debug("Route requested: '$route'", __METHOD__); $this->requestedRoute = $route; $result = $this->runAction($route, $params); if ($result instanceof Response) { return $result; } $response = $this->getResponse(); if ($result !== null) { $response->data = $result; } return $response; } catch (InvalidRouteException $e) { throw new NotFoundHttpException(Yii::t('yii', 'Page not found.'), $e->getCode(), $e); } }
Let's look at the runAction of yii base Module.
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) . '".'); }
Finally, $response - > send ();
public function send() { if ($this->isSent) { return; } $this->trigger(self::EVENT_BEFORE_SEND); //Get the format of $response and get the instance of the format object to execute the format method (header sets Content-Type) $this->prepare(); $this->trigger(self::EVENT_AFTER_PREPARE); $this->sendHeaders(); $this->sendContent(); $this->trigger(self::EVENT_AFTER_SEND); $this->isSent = true; }
summary
The overview and schematic diagram of the operation mechanism given by yii describe how an application handles a request.