Yii1.1原始碼解析2之根據路由查詢控制器
阿新 • • 發佈:2019-01-23
檔案路徑/framework/web/CWebApplication.php /** * Creates a controller instance based on a route. * The route should contain the controller ID and the action ID. * It may also contain additional GET variables. All these must be concatenated together with slashes. * * This method will attempt to create a controller in the following order: * <ol> * <li>If the first segment is found in {@link controllerMap}, the corresponding * controller configuration will be used to create the controller;</li> * <li>If the first segment is found to be a module ID, the corresponding module * will be used to create the controller;</li> * <li>Otherwise, it will search under the {@link controllerPath} to create * the corresponding controller. For example, if the route is "admin/user/create", * then the controller will be created using the class file "protected/controllers/admin/UserController.php".</li> * </ol> * @param string $route the route of the request. * @param CWebModule $owner the module that the new controller will belong to. Defaults to null, meaning the application * instance is the owner. * @return array the controller instance and the action ID. Null if the controller class does not exist or the route is invalid. * localhost:test.com/api/train/product/dosomething */ public function createController($route,$owner=null) { if($owner===null) $owner=$this; if(($route=trim($route,'/'))==='') $route=$owner->defaultController; $caseSensitive=$this->getUrlManager()->caseSensitive; $route.='/'; while(($pos=strpos($route,'/'))!==false) { $id=substr($route,0,$pos); if(!preg_match('/^\w+$/',$id)) return null; if(!$caseSensitive) $id=strtolower($id); $route=(string)substr($route,$pos+1); if(!isset($basePath)) // first segment { if(isset($owner->controllerMap[$id])) { return array( Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner), $this->parseActionParams($route), ); } 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'; if($owner->controllerNamespace!==null) $className=$owner->controllerNamespace.'\\'.str_replace('/','\\',$controllerID).$className; 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; } }
我們的分析的地址比如:test.com/api/train/product/dosomething
先分析第一個引數比如api
1、會分析配置(這裡一般是main.php)沒見裡有沒有controllerMap或模組這個配置,這是配置了api這個模組,所以路徑在/modules/
2、(api)配置成了模組,這時候的路徑就是/modules/api/
3、(train)如果不是模組,就是搜尋有沒有/modules/api/controllers/trainController.php,如果沒有就是目錄,這時候的路徑是:/modules/api/train/
4、(product)就會把當前的引數,拼接成productController.php檔案,比如/modules/api/controllers/train/controllers/productController.php,這次找到這個路徑了,載入檔案
總結,所以就算你的controller放的路徑再深,路由都能找到,不用擔心,因為這是用迴圈遍歷的。