復制代碼 代碼如下:
 
================================================================================================= 
//1.runController是執(zhí)行一個controller的方法,$route是$_GET['r'] 
public function runController($route) 
{ 
//在這里調(diào)用createController先去創(chuàng)建一個controller實例,由此可見createController是選擇controller的關鍵 
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))); 
} 
================================================================================================== 
//2.接下來我們分析createController,假設我們訪問的route是site/contact 
public function createController($route,$owner=null) 
{ 
//首次進入這個函數(shù),$owner參數(shù)為空 
if($owner===null) 
$owner=$this; 
//如果$route參數(shù)中不含/,那么使用默認的controller 
if(($route=trim($route,'/'))==='') 
$route=$owner->defaultController; 
$caseSensitive=$this->getUrlManager()->caseSensitive; 
//為了能夠完整運行下面的循環(huán),給$route后面加一個/ 
$route.='/'; 
//將/的位置保存在$pos中 
while(($pos=strpos($route,'/'))!==false) 
{ 
//$id是前半部分,即site 
$id=substr($route,0,$pos); 
if(!preg_match('/^/w+$/',$id)) 
return null; 
if(!$caseSensitive) 
$id=strtolower($id); 
//$route變成后半部分,即contact 
$route=(string)substr($route,$pos+1); 
//controller根目錄或子目錄前綴 
if(!isset($basePath)) // first segment 
{ 
//首次進入,$owner為空,沒有這個成員變量 
//非首次進入或$owner有值,有可能設置了這個成員變量,參見CWebModule類 
if(isset($owner->controllerMap[$id])) 
{ 
return array( 
Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner), 
$this->parseActionParams($route), 
); 
} 
//如果能通過getModule方法獲取到一個獨立模塊,則再次調(diào)用createController,適用于site是module名的情況,參考protected/config/main.php配置文件,例如你的controller在%webroot%/protected/module/site/controller/ContactController.php 
if(($module=$owner->getModule($id))!==null) 
return $this->createController($route,$module); 
//controller的目錄: 
//對于CWebApplication,對應config['basePath'](參見配置文件)./controller/,例如你的controller在%webroot%/protected/controller/SiteController.php 
//對于CModule的子類,對應改子類所在文件夾./contoller/,例如你的controller在%webroot%/protected/module/site/controller/ContactController.php 
$basePath=$owner->getControllerPath(); 
$controllerID=''; 
} 
else 
$controllerID.='/'; 
$className=ucfirst($id).'Controller'; 
$classFile=$basePath.DIRECTORY_SEPARATOR.$className.'.php'; 
//如果$classFile存在,根據(jù)上面所得到的controller類文件路徑,創(chuàng)建類實例 
//如果不存在,則是子目錄下的controller,繼續(xù)循環(huán)尋找最終的controller,例如你的controller在%webroot%/protected/controller/somedir/SiteController 
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; 
} 
$controllerID.=$id; 
$basePath.=DIRECTORY_SEPARATOR.$id; 
} 
}  
新聞熱點
疑難解答