·您现在的位置: 江北区云翼计算机软件开发服务部 >> 文章中心 >> 网站建设 >> 网站建设开发 >> php网站开发 >> 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