


Yii framework analysis (4) - Detailed analysis of WebApplication's run function
Dec 27, 2016 am 11:15 AMThe last sentence of the entry script of the Yii application starts the WebApplication
Yii::createWebApplication($config)->run();
CApplication:
public function run() { $this->onBeginRequest(new CEvent($this)); $this->processRequest(); $this->onEndRequest(new CEvent($this)); }
processRequest () starts processing the request, implemented by CWebApplication:
public function processRequest() { if(is_array($this->catchAllRequest) && isset($this->catchAllRequest[0])) { $route=$this->catchAllRequest[0]; foreach(array_splice($this->catchAllRequest,1) as $name=>$value) $_GET[$name]=$value; } else $route=$this->getUrlManager()->parseUrl($this->getRequest()); $this->runController($route); }
urlManager application component's parseUrl() creates $route (a string in the form of controllerID/actionID), and runController() creates a Controller object to start processing http requests. The value of
$route may have the following situations:
- empty: replaced by defaultController value;
- “moduleID/controllerID/actionID”:
- “controllerID under module /actionID”: The most common form
- “folder1/folder2/controllerID/actionID” Controller in a multi-level directory
runController first calls createController() to create a controller object
public function createController($route,$owner=null) { // $owner為空則設(shè)置為$this,即 $_app對(duì)象 if($owner===null) $owner=$this; // $route為空設(shè)置為defaultController,在$config里配置 if(($route=trim($route,’/'))===”) $route=$owner->defaultController; $caseSensitive=$this->getUrlManager()->caseSensitive; $route.=’/'; // 逐一取出 $route 按 ‘/’分割后的第一段進(jìn)行處理 while(($pos=strpos($route,’/'))!==false) { // $id 里存放的是 $route 第一個(gè) ‘/’前的部分 $id=substr($route,0,$pos); if(!preg_match(‘/^\w+$/’,$id)) return null; if(!$caseSensitive) $id=strtolower($id); // $route 存放’/’后面部分 $route=(string)substr($route,$pos+1); if(!isset($basePath)) // 完整$route的第一段 { // 如果$id在controllerMap[]里做了映射 // 直接根據(jù)$id創(chuàng)建controller對(duì)象 if(isset($owner->controllerMap[$id])) { return array( Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner), $this->parseActionParams($route), ); } // $id 是系統(tǒng)已定義的 module,根據(jù)$id取得module對(duì)象作為$owner參數(shù)來(lái)createController if(($module=$owner->getModule($id))!==null) return $this->createController($route,$module); // 控制器所在的目錄 $basePath=$owner->getControllerPath(); $controllerID=”; } else $controllerID.=’/'; $className=ucfirst($id).’Controller’; $classFile=$basePath.DIRECTORY_SEPARATOR.$className.’.php’; // 控制器類(lèi)文件存在,則require并創(chuàng)建控制器對(duì)象&返回 if(is_file($classFile)) { if(!class_exists($className,false)) require($classFile); if(class_exists($className,false) && is_subclass_of($className,’CController’)) { $id[0]=strtolower($id[0]); return array( new $className($controllerID.$id,$owner===$this?null:$owner), $this->parseActionParams($route), ); } return null; } // 未找到控制器類(lèi)文件,可能是多級(jí)目錄,繼續(xù)往子目錄搜索 $controllerID.=$id; $basePath.=DIRECTORY_SEPARATOR.$id; } }
createController() returns a created controller object and actionID. runController() calls the controller's init() method and run($actionID) to run the controller:
public function runController($route) { if(($ca=$this->createController($route))!==null) { list($controller,$actionID)=$ca; $oldController=$this->_controller; $this->_controller=$controller; $controller->init(); $controller->run($actionID); $this->_controller=$oldController; } else throw new CHttpException( 404, Yii::t(‘yii’,'Unable to resolve the request “{route}”.’, array( ‘{route}’=>$route===” ? $this->defaultController:$route))); }
$controller->init (), there is no action. The Action object is first created in run():
public function run($actionID) { if(($action=$this->createAction($actionID))!==null) { if(($parent=$this->getModule())===null) $parent=Yii::app(); if($parent->beforeControllerAction($this,$action)) { $this->runActionWithFilters($action,$this->filters()); $parent->afterControllerAction($this,$action); } } else $this->missingAction($actionID); }
$controller->run($actionID):
public function createAction($actionID) { // 為空設(shè)置為defaultAction if($actionID===”) $actionID=$this->defaultAction; // 控制器里存在 ‘a(chǎn)ction’.$actionID 的方法,創(chuàng)建CInlineAction對(duì)象 if(method_exists($this,’action’.$actionID) && strcasecmp($actionID,’s')) // we have actions method return new CInlineAction($this,$actionID); // 否則根據(jù)actions映射來(lái)創(chuàng)建Action對(duì)象 else return $this->createActionFromMap($this->actions(),$actionID,$actionID); }
Here you can see that the controller is not directly The action method is called, but an Action object is needed to run the controller action. This unifies the processing of actions by the action object mapped by the controller method and actions. That is, both forms of action processing are unified into the run( of the IAction interface). )transfer.
The IAction interface requires the implementation of three methods: run(), getId(), and getController (). The CAction class provided by Yii requires the constructor to provide the Controller and Id and implements the processing of getId() and getController (). The Action class can inherit from CAction.
CInlineAction is a very simple process under web/action. It calls the action method of the Controller:
class CInlineAction extends CAction { public function run() { $method=’action’.$this->getId(); $this->getController()->$method(); } }
Return to $controller->run($actionID)
public function run($actionID) { if(($action=$this->createAction($actionID))!==null) { if(($parent=$this->getModule())===null) $parent=Yii::app(); if($parent->beforeControllerAction($this,$action)) { $this->runActionWithFilters($action,$this->filters()); $parent->afterControllerAction($this,$action); } } else $this->missingAction($actionID); }
Yii::app()->beforeControllerAction() actually returns true, so the action object is actually run through the controller's runActionWithFilters()
public function runActionWithFilters($action,$filters) { // 控制器里沒(méi)有設(shè)置過(guò)濾器 if(empty($filters)) $this->runAction($action); else { // 創(chuàng)建過(guò)濾器鏈對(duì)象并運(yùn)行 $priorAction=$this->_action; $this->_action=$action; CFilterChain::create($this,$action,$filters)->run(); $this->_action=$priorAction; } }
No filter , runAction() is the run() method that ultimately calls the previously created action object:
public function runAction($action) { $priorAction=$this->_action; $this->_action=$action; if($this->beforeAction($action)) { $action->run(); $this->afterAction($action); } $this->_action=$priorAction; }
Each filter must implement the IFilter interface, and the preFilter() method implemented by the filter is in $action->run( ), if it is judged that the action can be executed, it will return true, otherwise it will return false
if($filter1->preFilter())
if($filter2->preFilter())
if($filtern->preFilter())
$action->run()
$filtern->postFilter()
$filter2->postFilter()
$filter1- >postFilter()
The most common operation in action is to render the view file: renderPartial() and render(). render() will put the result into the layout file after processing the view file.
public function renderPartial($view,$data=null,$return=false,$processOutput=false) { if(($viewFile=$this->getViewFile($view))!==false) { $output=$this->renderFile($viewFile,$data,true); if($processOutput) $output=$this->processOutput($output); if($return) return $output; else echo $output; } else throw new CException(Yii::t(‘yii’,'{controller} cannot find the requested view “{view}”.’, array(‘{controller}’=>get_class($this), ‘{view}’=>$view))); }
getViewFile($view) gets the full path of $view:
$view starts with '/', uses the system views directory as the starting directory +$view+.php
$view contains For aliases, find the real path of the alias
Others use the modele view directory as the starting directory+$view+.php
If the third-party renderer is not configured in $config, the actual value in renderFile() is The renderInternal() provided by Yii itself is called to render the view file:
public function renderFile($viewFile,$data=null,$return=false) { $widgetCount=count($this->_widgetStack); // 如果配置了其他的ViewRenderer if(($renderer=Yii::app()->getViewRenderer())!==null) $content=$renderer->renderFile($this,$viewFile,$data,$return); else // yii 自身的render $content=$this->renderInternal($viewFile,$data,$return); if(count($this->_widgetStack)===$widgetCount) return $content; else { $widget=end($this->_widgetStack); throw new CException(Yii::t(‘yii’,'{controller} contains improperly nested widget tags in its view “{view}”. A {widget} widget does not have an endWidget() call.’,array(‘{controller}’=>get_class($this), ‘{view}’=>$viewFile, ‘{widget}’=>get_class($widget)))); } }
Yii's renderer uses PHP itself as the template system:
public function renderInternal($_viewFile_,$_data_=null,$_return_=false) { // extract函數(shù)將$_data_從數(shù)組中將變量導(dǎo)入到當(dāng)前的符號(hào)表 if(is_array($_data_)) extract($_data_,EXTR_PREFIX_SAME,’data’); else $data=$_data_; if($_return_) { ob_start(); ob_implicit_flush(false); require($_viewFile_); return ob_get_clean(); } else require($_viewFile_); }
render() actually renders the Partial view first file, then renderFile layoutfile, and pass in the result of the view file as the $content variable.
public function render($view,$data=null,$return=false) { $output=$this->renderPartial($view,$data,true); if(($layoutFile=$this->getLayoutFile($this->layout))!==false) $output=$this->renderFile($layoutFile,array(‘content’=>$output),true); $output=$this->processOutput($output); if($return) return $output; else echo $output; }
processOutput processes the render results, such as adding css or js scripts to the head.
public function processOutput ($output) { Yii::app()->getClientScript()->render($output); // if using page caching, we should delay dynamic output replacement if($this->_dynamicOutput!==null && $this->isCachingStackEmpty()) $output=$this->processDynamicOutput($output); if($this->_pageStates===null) $this->_pageStates=$this->loadPageStates(); if(!empty($this->_pageStates)) $this->savePageStates($this->_pageStates,$output); return $output; }
The above is the detailed analysis of Yii framework analysis (4) - WebApplication's run function. For more related content, please pay attention to the PHP Chinese website (www.miracleart.cn)!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Yii framework middleware: providing multiple data storage support for applications Introduction Middleware (middleware) is an important concept in the Yii framework, which provides multiple data storage support for applications. Middleware acts like a filter, inserting custom code between an application's requests and responses. Through middleware, we can process, verify, filter requests, and then pass the processed results to the next middleware or final handler. Middleware in the Yii framework is very easy to use

In recent years, with the rapid development of the game industry, more and more players have begun to look for game strategies to help them pass the game. Therefore, creating a game guide website can make it easier for players to obtain game guides, and at the same time, it can also provide players with a better gaming experience. When creating such a website, we can use the Yii framework for development. The Yii framework is a web application development framework based on the PHP programming language. It has the characteristics of high efficiency, security, and strong scalability, and can help us create a game guide more quickly and efficiently.

Yii framework middleware: Add logging and debugging capabilities to applications [Introduction] When developing web applications, we usually need to add some additional features to improve the performance and stability of the application. The Yii framework provides the concept of middleware that enables us to perform some additional tasks before and after the application handles the request. This article will introduce how to use the middleware function of the Yii framework to implement logging and debugging functions. [What is middleware] Middleware refers to the processing of requests and responses before and after the application processes the request.

With the rapid development of web applications, modern web development has become an important skill. Many frameworks and tools are available for developing efficient web applications, among which the Yii framework is a very popular framework. Yii is a high-performance, component-based PHP framework that uses the latest design patterns and technologies, provides powerful tools and components, and is ideal for building complex web applications. In this article, we will discuss how to use Yii framework to build web applications. Install Yii framework first,

Steps to implement web page caching and page chunking using the Yii framework Introduction: During the web development process, in order to improve the performance and user experience of the website, it is often necessary to cache and chunk the page. The Yii framework provides powerful caching and layout functions, which can help developers quickly implement web page caching and page chunking. This article will introduce how to use the Yii framework to implement web page caching and page chunking. 1. Turn on web page caching. In the Yii framework, web page caching can be turned on through the configuration file. Open the main configuration file co

In the Yii framework, controllers play an important role in processing requests. In addition to handling regular page requests, controllers can also be used to handle Ajax requests. This article will introduce how to handle Ajax requests in the Yii framework and provide code examples. In the Yii framework, processing Ajax requests can be carried out through the following steps: The first step is to create a controller (Controller) class. You can inherit the basic controller class yiiwebCo provided by the Yii framework

In modern web application development, debugging tools are indispensable. They help developers find and solve various problems with their applications. As a popular web application framework, the Yii framework naturally provides some debugging tools. This article will focus on the debugging tools in the Yii framework and discuss how they help us analyze and debug applications. GiiGii is a code generator for the Yii framework. It can automatically generate code for Yii applications, such as models, controllers, views, etc. Using Gii,

Encrypting and decrypting sensitive data using Yii framework middleware Introduction: In modern Internet applications, privacy and data security are very important issues. To ensure that users' sensitive data is not accessible to unauthorized visitors, we need to encrypt this data. The Yii framework provides us with a simple and effective way to implement the functions of encrypting and decrypting sensitive data. In this article, we’ll cover how to achieve this using the Yii framework’s middleware. Introduction to Yii framework Yii framework is a high-performance PHP framework.
