Vendor/yiisoft/yii2/base/module. PHP (cont.)
/** * This method parses the specified route and creates the corresponding submodule (s), Controller and action * This method parses the specified route and creates the corresponding child Module (s), Controller and action * instances. It then calls [[Controller::runaction ()]] to run the action with the given parameters. * If the path is empty, the method uses [[Defaultroute]] * @param string $route The route that specifies the action. * @param array $params The parameters to being passed to the action * @return mixed the result of the action. * @throws Invalidrouteexception If the requested route cannot be resolved to an action successfully*/ Public functionRunaction ($route,$params= []) { //Create the controller, get the instance of the controller and the ID of the action $parts=$this->createcontroller ($route); if(Is_array($parts)) { /*@var $controller Controller*/ List($controller,$actionID) =$parts; //keep the controller that is bound in the app $oldController= Yii::$app-Controller; //bind the current controller to the appYII::$app->controller =$controller; $result=$controller->runaction ($actionID,$params); //Restore the controller that was previously bound to the appYII::$app->controller =$oldController; return $result; } Else { $id=$this-Getuniqueid (); Throw NewInvalidrouteexception (' Unable to resolve the request '. ($id= = = '?$route:$id. ‘/‘ .$route) . ‘".‘); } } /** * Create a new controller instance based on the given route. * * The route should be relative to this module. The method implements the following algorithm * To resolve the given route: * * 1. If the route is empty, use [[Defaultroute]]; * 2. If the first segment of the route is a valid module ID as declared in [[modules]], * Call the module ' s ' createcontr Oller () ' with the rest part of the route; * 3. If the first segment of the route is found in [[Controllermap]], create a controller * based on the corresponding C Onfiguration found in [[Controllermap]]; * 4. The given route is in the format of ' abc/def/xyz '. Try either ' abc\defcontroller ' * or ' Abc\def\xyzcontroller ' class within the [Controllernamespace|controller names Pace]]. * If any of the above steps resolves to a controller, it is returned together with the rest * part of the rout E which'll be treated as the action ID. Otherwise, False would be returned. * * @param string $route The route consisting of module, controller and action IDs. * @returnArray|boolean IF The controller is created successfully, it'll be a returned together * with the requested action ID. Otherwise false would be returned. * @throws Invalidconfigexception if the controller class and its file does not match.*/ Public functionCreatecontroller ($route) { if($route= = = "") { $route=$this-Defaultroute; } //double slashes or leading/ending slashes may cause substr problem//If there is a double slash or an ending slash, it can cause problems $route=Trim($route, ‘/‘); if(Strpos($route, '//')!==false) { return false; } if(Strpos($route, '/')!==false) { //If there is a slash, divide the route according to a slash and limit the maximum number of partitions to two List($id,$route) =Explode(‘/‘,$route, 2); } Else { //does not exist, it is directly assigned to $id $id=$route; $route= ' '; } //module and controller map take precedence if(isset($this->controllermap[$id])) { //if there is a corresponding $id in the Controllermap, use Yii::createobject to create an instance of the controller $controller= Yii::createobject ($this->controllermap[$id], [$id,$this]); return[$controller,$route]; } //get module by ID $module=$this->getmodule ($id); if($module!==NULL) { //gets to the module, recursively calls the corresponding module's createcontroller to create an instance of the controller return $module->createcontroller ($route); } //If you take the module, you need to continue to take the controller's ID//split again according to the slash if(($pos=Strrpos($route, '/'))!==false) { //If there is a slash, the ID of the module is combined with the contents of the subsequent intercept to spell the ID $id. = '/'.substr($route, 0,$pos); //the remaining assignment to Route $route=substr($route,$pos+ 1); } //then create an instance of the controller based on the ID . $controller=$this->createcontrollerbyid ($id); //not created successfully, and the route is not empty if($controller===NULL&&$route!== ") { //stitch the route into the ID and create an instance of the controller again $controller=$this->createcontrollerbyid ($id. ‘/‘ .$route); $route= ' '; } return $controller===NULL?false: [$controller,$route]; } /** * Create a controller based on the given controller ID. * * The controller ID is relative to this module. The Controller class * should be namespaced under [[Controllernamespace]]. * * Note that this method does not check [[modules]] or [[Controllermap]]. * * @param string $ID the Controller ID * @return Controller The newly created controller instance, or null if the Controller ID is invalid. * @throws Invalidconfigexception if the controller class and its file name does not match. * This exception are only thrown when in debug mode. */ Public functionCreatecontrollerbyid ($id) { //$id is the controller's ID, but it may have a module ID in front of it, and may be a multi-level module ID//Take the rightmost slash position to isolate the controller's name $pos=Strrpos($id, ‘/‘); if($pos===false) { //no Slash, $id's the controller's name. $prefix= ' '; $className=$id; } Else { //There is a slash, before the slash is the module ID, slash after the controller's name $prefix=substr($id, 0,$pos+ 1); $className=substr($id,$pos+ 1); } if(!Preg_match('%^[a-z][a-z0-9\\-_]*$% ',$className)) { //if the controller's name does not conform to the named specification, it returns NULL//starts with a lowercase letter, can contain a number/lowercase letter/Right slash/dash/ underline return NULL; } if($prefix!== ' &&!Preg_match('%^[a-z0-9_/]+$%i ',$prefix)) { //if the module's ID does not conform to the module's naming specification, it returns NULL//can contain a number/lowercase letter/left slash/ underscore return NULL; } //first, replace with a space, then capitalize the first letter of each word, replace the space with an empty string, and finally stitch the ' Controller ' to get the class name (without namespace) $className=Str_replace(‘ ‘, ‘‘,Ucwords(Str_replace(‘-‘, ‘ ‘,$className))) . ' Controller '; //The class name of the controller is spelled out according to the Controllernamespace defined in application and module, including namespace $className=LTrim($this->controllernamespace. ‘\\‘ .Str_replace(‘/‘, ‘\\‘,$prefix) .$className, ‘\\‘); if(Strpos($className, '-')!==false|| !class_exists($className)) { //returns NULL if there is an underscore or if the class does not exist return NULL; } //is_subclass_of-If this object is a subclass of the class, returns TRUE//determines if the subclass of ' Yii\base\controller ' is not, then creates an instance of the corresponding class if(is_subclass_of($className, ' Yii\base\controller ')) { returnYii::createobject ($className, [$id,$this]); } ElseIf(yii_debug) {Throw NewInvalidconfigexception ("Controller class must extend from \\yii\\base\\Controller."); } Else { return NULL; } }
Learning yii2.0 Framework Read code (11)