轉載請注明:TheViperhttp://m.survivalescaperooms.com/TheViper/
上一篇主要分析了Yii::createWebapplication ( $config )->run ();的createWebApplication ( $config )部分,這篇分析后面的。
run()也是不在CWebApplication里面,在CApplication 里。
1 <?php 2 abstract class CApplication extends CModule { 3 PRivate $_id; 4 private $_basePath; 5 abstract public function processRequest(); 6 public function __construct($config = null) { 7 if (is_string ( $config )) 8 $config = require ($config); 9 Yii::setApplication ( $this );//保存整個app實例10 if (isset ( $config ['basePath'] )) {11 $this->setBasePath ( $config ['basePath'] );12 unset ( $config ['basePath'] );13 } else14 $this->setBasePath ( 'protected' );15 //設置別名,后面就可以用application表示basePath了16 Yii::setPathOfAlias ( 'application', $this->getBasePath () );17 //鉤子,模塊 預 初始化時執行,子類實現。不過這時,配置還沒有寫入框架18 $this->preinit ();19 $this->registerCoreComponents ();20 //父類實現21 $this->configure ( $config );22 //加載靜態應用組件23 $this->preloadComponents ();24 //這才開始初始化模塊25 $this->init ();26 }27 protected function registerCoreComponents() {28 $components = array (29 'request' => array (30 'class' => 'CHttpRequest'31 ),32 'urlManager' => array (33 'class' => 'CUrlManager'34 )35 );36 37 $this->setComponents ( $components );//父類實現38 }39 public function run() {40 $this->processRequest ();41 }42 public function getId() {43 if ($this->_id !== null)44 return $this->_id;45 else46 return $this->_id = sprintf ( '%x', crc32 ( $this->getBasePath () . $this->name ) );47 }48 public function setId($id) {49 $this->_id = $id;50 }51 public function getBasePath() {52 return $this->_basePath;53 }54 public function setBasePath($path) {55 if (($this->_basePath = realpath ( $path )) === false || ! is_dir ( $this->_basePath ))56 return;57 }58 public function getDb() {59 return $this->getComponent ( 'db' );//父類實現60 }61 public function getUrlManager() {62 return $this->getComponent ( 'urlManager' );63 }64 public function getController() {65 return null;66 }67 public function getBaseUrl($absolute = false) {68 return $this->getRequest ()->getBaseUrl ( $absolute );69 }70 }
run()又用了CWebApplication里面的processRequest()。薛強大哥(yii作者),架構要不要這樣啊.裁剪后當然覺得這樣的調用很沒意思。
后面的主要在CWebApplication里了。
 1 <?php 2 class CWebApplication extends CApplication { 3     public $controllerNamespace; 4     private $_controllerPath; 5     private $_viewPath; 6     private $_systemViewPath; 7     private $_controller; 8     public $controllerMap=array(); 9     public function processRequest() {//開始執行請求10         //獲取urlManager組件,解析請求,得到controller/action這種格式的string,11         //并且將隱藏參數與請求的參數一一對應,匹配起來,寫入$_REQUEST中12         $route = $this->getUrlManager ()->parseUrl ($this->getRequest());13         $this->runController ( $route );14     }15     public function getRequest() {//獲取request組件16         return $this->getComponent ( 'request' );17     }18     protected function registerCoreComponents() {//注冊核心組件19         parent::registerCoreComponents ();20     }21     //執行contronller22     public function runController($route) {23         if (($ca = $this->createController ( $route )) !== null) {24             list ( $controller, $actionID ) = $ca;25             $oldController = $this->_controller;26             $this->_controller = $controller;27             $controller->init ();//鉤子,在執行action方法前調用,子類去實現28             $controller->run ( $actionID );//開始轉入controller類中action方法的執行29             $this->_controller = $oldController;30         }31     }32     //創建controller類實例,從controller/action這種格式的string中解析出$controller, $actionID 33     public function createController($route, $owner = null) {34         if ($owner === null)35             $owner = $this;36         if (($route = trim ( $route, '/' )) === '')37             $route = $owner->defaultController;38 39         $route .= '/';40         while ( ($pos = strpos ( $route, '/' )) !== false ) {41             $id = substr ( $route, 0, $pos );42             if (! preg_match ( '/^/w+$/', $id ))43                 return null;44             $id = strtolower ( $id );45             $route = ( string ) substr ( $route, $pos + 1 );46             if (! isset ( $basePath ))             // first segment47             {48                 $basePath = $owner->getControllerPath ();49                 $controllerID = '';50             } else {51                 $controllerID .= '/';52             }53             $className = ucfirst ( $id ) . 'Controller';54             $classFile = $basePath . DIRECTORY_SEPARATOR . $className . '.php';55 56             if (is_file ( $classFile )) {57                 if (! class_exists ( $className, false ))58                     require ($classFile);59                 if (class_exists ( $className, false ) && is_subclass_of ( $className, 'CController' )) {60                     $id [0] = strtolower ( $id [0] );61                     return array (62                             new $className ( $controllerID . $id, $owner === $this ? null : $owner ),63                             $this->parseActionParams ( $route )64                     );65                 }66                 return null;67             }68             $controllerID .= $id;69             $basePath .= DIRECTORY_SEPARATOR . $id;70         }71     }72     protected function parseActionParams($pathInfo) {73         if (($pos = strpos ( $pathInfo, '/' )) !== false) {74             $manager = $this->getUrlManager ();//再次獲取urlManager,在上面第一次調用中已經導入。75             $manager->parsePathInfo ( ( string ) substr ( $pathInfo, $pos + 1 ) );76             $actionID = substr ( $pathInfo, 0, $pos );77             return $manager->caseSensitive ? $actionID : strtolower ( $actionID );78         } else79             return $pathInfo;80     }81     public function getControllerPath() {82         if ($this->_controllerPath !== null)83             return $this->_controllerPath;84         else85             return $this->_controllerPath = $this->getBasePath () . DIRECTORY_SEPARATOR . 'controllers';86     }87     //兩個鉤子,子類去實現88     public function beforeControllerAction($controller, $action) {89         return true;90     }91     public function afterControllerAction($controller, $action) {92     }93     protected function init() {94         parent::init ();95     }96 }對于$this->getUrlManager (),YiiBase里面有'CUrlManager' => 'CUrlManager.php'這個映射,說明是實例化了CUrlManager這個類。
 1 <?php 2 class CUrlManager { 3     const GET_FORMAT = 'get'; 4     public $rules = array (); 5     public $urlSuffix = ''; 6     public $caseSensitive = true; 7     public $urlRuleClass = 'CUrlRule'; 8     private $_urlFormat = self::GET_FORMAT; 9     private $_rules = array ();10     private $_baseUrl;11     protected function processRules() {12         //遍歷自定義的請求匹配規則13         foreach ( $this->rules as $pattern => $route ) {14             //對每一個規則創建CUrlRule實例15             $this->_rules [] = $this->createUrlRule ( $route, $pattern );16         }17     }18     protected function createUrlRule($route, $pattern) {19         if (is_array ( $route ) && isset ( $route ['class'] ))20             return $route;21         else {22             //import第二個參數表示是否立即包含類文件。 如果為flase,則類文件僅在被使用時包含。 這個參數僅當使用一個類的路徑 別名 時才會用到23             $urlRuleClass = Yii::import ( $this->urlRuleClass, true );24             //創建CUrlRule實例25             return new $urlRuleClass ( $route, $pattern );26         }27     }28     //類似于__construct()29     public function init() {30         $this->processRules ();31     }32     public fu
新聞熱點
疑難解答