Yii應(yīng)用的入口腳本最后一句啟動了WebApplication
Yii::createWebApplication($config)->run();
CApplication:
public function run() { $this->onBeginRequest(new CEvent($this)); $this->processRequest(); $this->onEndRequest(new CEvent($this)); }
processRequest()開始處理請求,由CWebApplication實(shí)現(xiàn):
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應(yīng)用組件的parseUrl() 創(chuàng)建了$route (形式為controllerID/actionID的字符串),runController()創(chuàng)建Controller對象開始處理http請求。
$route 的值可能存在以下幾種情況:
- 為空: 用 defaultController 值代替;
- “moduleID/controllerID/actionID”: module下的
- “controllerID/actionID” : 最常見的形式
- “folder1/folder2/controllerID/actionID” 多級目錄下的控制器
runController首先調(diào)用createController()創(chuàng)建控制器對象
public function createController($route,$owner=null) { // $owner為空則設(shè)置為$this,即 $_app對象 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 第一個 ‘/’前的部分 $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對象 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對象作為$owner參數(shù)來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’; // 控制器類文件存在,則require并創(chuàng)建控制器對象&返回 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; } // 未找到控制器類文件,可能是多級目錄,繼續(xù)往子目錄搜索 $controllerID.=$id; $basePath.=DIRECTORY_SEPARATOR.$id; } }
createController() 返回一個創(chuàng)建好的控制器對象和actionID, runController()調(diào)用控制器的init()方法和run($actionID)來運(yùn)行控制器:
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()里沒有動作, 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)里首先創(chuàng)建了Action對象:
public function createAction($actionID) { // 為空設(shè)置為defaultAction if($actionID===”) $actionID=$this->defaultAction; // 控制器里存在 ‘a(chǎn)ction’.$actionID 的方法,創(chuàng)建CInlineAction對象 if(method_exists($this,’action’.$actionID) && strcasecmp($actionID,’s')) // we have actions method return new CInlineAction($this,$actionID); // 否則根據(jù)actions映射來創(chuàng)建Action對象 else return $this->createActionFromMap($this->actions(),$actionID,$actionID); }
這里可以看到控制器并不是直接調(diào)用了action方法,而是需要一個Action對象來運(yùn)行控制器動作,這樣就統(tǒng)一了控制器方法和actions映射的action對象對action的處理,即兩種形式的action處理都統(tǒng)一為IAction接口的run()調(diào)用。
IAction接口要求實(shí)現(xiàn)run(),getId(),getController () 三個方法,Yii提供的CAction類要求構(gòu)造函數(shù)提供Controller和Id并實(shí)現(xiàn)了getId()和getController ()的處理,Action類從CAction繼承即可。
CInlineAction在web/action下,run()是很簡單的處理過程,調(diào)用了Controller的action方法:
class CInlineAction extends CAction { public function run() { $method=’action’.$this->getId(); $this->getController()->$method(); } }
回到 $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() 實(shí)際是固定返回true的,所以action對象實(shí)際是通過控制器的runActionWithFilters()被run的
public function runActionWithFilters($action,$filters) { // 控制器里沒有設(shè)置過濾器 if(empty($filters)) $this->runAction($action); else { // 創(chuàng)建過濾器鏈對象并運(yùn)行 $priorAction=$this->_action; $this->_action=$action; CFilterChain::create($this,$action,$filters)->run(); $this->_action=$priorAction; } }
沒有過濾器,runAction()就是最終要調(diào)用前面創(chuàng)建的action對象的run()方法:
public function runAction($action) { $priorAction=$this->_action; $this->_action=$action; if($this->beforeAction($action)) { $action->run(); $this->afterAction($action); } $this->_action=$priorAction; }
每個filter都要實(shí)現(xiàn)IFilter接口,filter實(shí)現(xiàn)的preFilter()方法在$action->run()之前調(diào)用,如果判斷action可以執(zhí)行則返回true,否則返回false
if($filter1->preFilter())
if($filter2->preFilter())
if($filtern->preFilter())
$action->run()
$filtern->postFilter()
$filter2->postFilter()
$filter1->postFilter()
在action里最常見的操作就是render view文件: renderPartial()和render()。render()在處理view文件后會把結(jié)果放入layout文件內(nèi)。
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)獲得$view的完整路徑:
$view 以 ‘/’開頭的,以系統(tǒng)views目錄作為起始目錄+$view+.php
$view含有別名的,查找別名的真實(shí)路徑
其他的以modele view目錄作為起始目錄+$view+.php
如果沒有在$config里配置第三方的renderer,renderFile() 里實(shí)際是調(diào)用了yii自身提供的renderInternal()來render view文件:
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的renderer用的是php本身作為模板系統(tǒng):
public function renderInternal($_viewFile_,$_data_=null,$_return_=false) { // extract函數(shù)將$_data_從數(shù)組中將變量導(dǎo)入到當(dāng)前的符號表 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()的實(shí)際上是先renderPartial view文件,然后renderFile layoutfile,并將view文件的結(jié)果做為$content變量傳入。
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將render的結(jié)果再做處理,比如在head加上css或js腳本等。
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; }
?以上就是Yii框架分析(四)——WebApplication的run函數(shù)詳細(xì)解析的內(nèi)容,更多相關(guān)內(nèi)容請關(guān)注PHP中文網(wǎng)(www.miracleart.cn)!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Perisian tengah rangka kerja Yii: menyediakan sokongan storan data berbilang untuk aplikasi Pengenalan Middleware (perisian tengah) ialah konsep penting dalam rangka kerja Yii, yang menyediakan sokongan storan data berbilang untuk aplikasi. Middleware bertindak seperti penapis, memasukkan kod tersuai antara permintaan dan respons aplikasi. Melalui perisian tengah, kami boleh memproses, mengesahkan, menapis permintaan, dan kemudian menyerahkan hasil yang diproses kepada perisian tengah atau pengendali akhir yang seterusnya. Middleware dalam rangka kerja Yii sangat mudah digunakan

Perisian tengah rangka kerja Yii: Tambah keupayaan pengelogan dan penyahpepijatan pada aplikasi [Pengenalan] Semasa membangunkan aplikasi web, biasanya kami perlu menambah beberapa ciri tambahan untuk meningkatkan prestasi dan kestabilan aplikasi. Rangka kerja Yii menyediakan konsep perisian tengah yang membolehkan kami melaksanakan beberapa tugas tambahan sebelum dan selepas aplikasi mengendalikan permintaan. Artikel ini akan memperkenalkan cara menggunakan fungsi perisian tengah bagi rangka kerja Yii untuk melaksanakan fungsi pengelogan dan penyahpepijatan. [Apakah middleware] Middleware merujuk kepada pemprosesan permintaan dan respons sebelum dan selepas aplikasi memproses permintaan.

Dengan perkembangan pesat aplikasi web, pembangunan web moden telah menjadi kemahiran penting. Banyak rangka kerja dan alatan tersedia untuk membangunkan aplikasi web yang cekap, antaranya rangka kerja Yii adalah yang sangat popular. Yii ialah rangka kerja PHP berasaskan komponen berprestasi tinggi yang menggunakan corak dan teknologi reka bentuk terkini, menyediakan alatan dan komponen yang berkuasa serta sesuai untuk membina aplikasi web yang kompleks. Dalam artikel ini, kita akan membincangkan cara menggunakan rangka kerja Yii untuk membina aplikasi web. Pasang rangka kerja Yii dahulu,

Langkah-langkah untuk melaksanakan caching halaman web dan chunking halaman menggunakan rangka kerja Yii Pengenalan: Semasa proses pembangunan web, untuk meningkatkan prestasi dan pengalaman pengguna tapak web, selalunya perlu untuk cache dan chunk halaman. Rangka kerja Yii menyediakan fungsi caching dan reka letak yang berkuasa, yang boleh membantu pembangun melaksanakan caching halaman web dan chunking halaman dengan pantas Artikel ini akan memperkenalkan cara menggunakan rangka kerja Yii untuk melaksanakan caching halaman web dan chunking halaman. 1. Hidupkan caching halaman web Dalam rangka kerja Yii, caching halaman web boleh dihidupkan melalui fail konfigurasi. Buka fail konfigurasi utama co

Dalam rangka kerja Yii, pengawal memainkan peranan penting dalam memproses permintaan. Selain mengendalikan permintaan halaman biasa, pengawal juga boleh digunakan untuk mengendalikan permintaan Ajax. Artikel ini akan memperkenalkan cara mengendalikan permintaan Ajax dalam rangka kerja Yii dan memberikan contoh kod. Dalam rangka kerja Yii, pemprosesan permintaan Ajax boleh dijalankan melalui langkah-langkah berikut: Langkah pertama ialah mencipta kelas pengawal (Pengawal). Anda boleh mewarisi kelas pengawal asas yiiwebCo yang disediakan oleh rangka kerja Yii

Dalam pembangunan aplikasi web moden, alat penyahpepijatan amat diperlukan. Mereka membantu pembangun mencari dan menyelesaikan pelbagai masalah dengan aplikasi mereka. Sebagai rangka kerja aplikasi web yang popular, rangka kerja Yii secara semula jadi menyediakan beberapa alat penyahpepijatan. Artikel ini akan menumpukan pada alat penyahpepijatan dalam rangka kerja Yii dan membincangkan cara alat tersebut membantu kami menganalisis dan nyahpepijat aplikasi. GiiGii ialah penjana kod untuk rangka kerja Yii. Ia boleh menjana kod secara automatik untuk aplikasi Yii, seperti model, pengawal, paparan, dsb. Menggunakan Gii,

Menyulitkan dan menyahsulit data sensitif menggunakan perisian tengah rangka kerja Yii Pengenalan: Dalam aplikasi Internet moden, privasi dan keselamatan data adalah isu yang sangat penting. Untuk memastikan bahawa data sensitif pengguna tidak boleh diakses oleh pelawat yang tidak dibenarkan, kami perlu menyulitkan data ini. Rangka kerja Yii memberikan kami cara yang mudah dan berkesan untuk melaksanakan fungsi menyulitkan dan menyahsulit data sensitif. Dalam artikel ini, kami akan membincangkan cara untuk mencapai ini menggunakan perisian tengah rangka kerja Yii. Pengenalan kepada rangka kerja Yii Rangka kerja Yii ialah rangka kerja PHP berprestasi tinggi.

Apabila bersiap untuk temu bual dengan Rangka Kerja YII, anda perlu mengetahui perkara pengetahuan utama berikut: 1. Senibina MVC: Memahami karya kolaboratif model, pandangan dan pengawal. 2. Activerecord: Menguasai penggunaan alat ORM dan memudahkan operasi pangkalan data. 3. Widget dan pembantu: biasa dengan komponen terbina dalam dan fungsi penolong, dan dengan cepat membina antara muka pengguna. Menguasai konsep teras dan amalan terbaik ini akan membantu anda menonjol dalam wawancara.
