·您现在的位置: 江北区云翼计算机软件开发服务部 >> 文章中心 >> 网站建设 >> 网站建设开发 >> php网站开发 >> yii源码分析3

yii源码分析3

作者:佚名      php网站开发编辑:admin      更新时间:2022-07-23
yii源码分析3

转载请注明:TheViperhttp://www.cnblogs.com/TheViper/

上一篇说到CWebapplication中的¥route=$this->getUrlManager ()->parseUrl ($this->getRequest());,得到$route=controler/actionid。

这篇说他后面的$this->runController ( $route );

 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 }

$ca = $this->createController ( $route ));createController的作用是将$route中的controller和action分离出来,并创建controller实例。

最后返回controller实例和actionid.

然后回到CWebApplication的runController($route),$controller->init ();在controller初始化时执行,这个需要在子类中重写,比如:

 1 class VideoController extends CController { 2     public function init() { 3         $this->db = Yii::app ()->db; 4     } 5     public function actionBroadcast() { 6         $b = $this->db->query ( "", array (1 ) ); 7         $this->render ( "u_broadcast", array ( 8         'b' => $b [0] ; 9     ) );10     }11 }    

这样在VideoController中便可以用$this->db调用db组件了。

$controller->run ( $actionID );转入Ccontroller.

 1 <?php 2 class CController { 3     protected $db; 4     public $defaultAction = 'index'; 5     private $_id; 6     private $_action; 7     public function __construct($id, $module = null) { 8         $this->_id = $id; 9     }10     public function init() {11     }12     //过滤方法,子类重写13     public function filters() {14         return array ();15     }16     public function run($actionID) {17         //创建action实例18         if (($action = $this->createAction ( $actionID )) !== null) {19             $parent = Yii::app ();20             if ($parent->beforeControllerAction ( $this, $action )) {21                 $this->runActionWithFilters ( $action, $this->filters () );22                 $parent->afterControllerAction ( $this, $action );23             }24         }25     }26     public function refresh($terminate = true, $anchor = '') {27         $this->redirect ( Yii::app ()->getRequest ()->getUrl () . $anchor, $terminate );28     }29     public function redirect($url, $terminate = true, $statusCode = 302) {30         Yii::app ()->getRequest ()->redirect ( $url, $terminate, $statusCode );31     }32     //如果controller里面有filter33     public function runActionWithFilters($action, $filters) {34         if (empty ( $filters ))35             $this->runAction ( $action );36         else {37             $priorAction = $this->_action;38             $this->_action = $action;39             CFilterChain::create ( $this, $action, $filters )->run ();40             $this->_action = $priorAction;41         }42     }43     public function runAction($action) {44         $priorAction = $this->_action;45         $this->_action = $action;46         if ($this->beforeAction ( $action )) {47             if ($action->runWithParams ( $this->getActionParams () ) === false)48                 $this->invalidActionParams ( $action );49             else50                 $this->afterAction ( $action );51         }52         $this->_action = $priorAction;53     }54     //渲染视图55     public function render($view, $data = array()) {56         if (isset ( $data ))57             extract ( $data );58         include VIEWS_DIR . "/" . $this->_id . "/" . $view . ".php";59     }60     public function renderFile($file, $data = array()) {61         if (isset ( $data ))62             extract ( $data );63         include VIEWS_DIR . "/" . $file;64     }65     //跳转到另一个controller/action,不过浏览器的地址没有变66     public function forward($route) {67         if (strpos ( $route, '/' ) === false)68             $this->run ( $route );69         else {70             //不在同一个controller里面,重新创建71             Yii::app ()->runController ( $route );72         }73     }74     public function getActionParams() {75         return $_GET;76     }77     public function createAction($actionID) {78         if ($actionID === '')79             $actionID = $this->defaultAction;80         if (method_exists ( $this, 'action' . $actionID ) && strcasecmp ( $actionID, 's' ))81             return new CInlineAction ( $this, $actionID );82     }83     publ