Describes how to create a controller (createController) in Yii2. Default controller in yii2
This example describes how to create a controller (createController) in yii2. We will share this with you for your reference. The details are as follows:
In yii, the controller is created by parsing the routing information through UrlManager in the request in the application, and then in the yii \ base \ Module
public function runAction($route, $params = [])
Method To create a controller, and then the Controller executes the corresponding action.
First, make it clear that,Routes in Yii are divided into three situations:
The first type is module id/controller id/action id ),
The second type is sub dir/controller id/action id with a namespace (subdirectory)
The third type is only controller and action (controller id/action id)
These three are prioritized. Therefore, when creating a controller, you must first check whether it is a module-type route. If yes, you can obtain this module and then create a controller.
Then judge whether the second type has a namespace.
Public function createController ($ route) {// if the route is empty, use the default route if ($ route = '') {$ route = $ this-> defaultRoute;} // double slashes or leading/ending slashes may cause substr problem // remove the backslash ("/") at the beginning and end, if the route contains "//", false is returned and creation fails. $ Route = trim ($ route, '/'); if (strpos ($ route ,'//')! = False) {return false;}/** there are three routing conditions: * module id, controller id, and action id ), * sub dir/controller id/action id with a namespace (sub-directory) * The controller id and action id only) * Here, we need to separate the first "/" into two parts, $ id and $ route information, */if (strpos ($ route ,'/')! = False) {list ($ id, $ route) = explode ('/', $ route, 2);} else {$ id = $ route; $ route = '';} // module and controller map take precedence/** check whether this id is a module. If it is a module, use this module to create a controller. * If the name of a controller is the same as that of a module, the Controller in the module is created first. ** If there is a url: http://www.yii2.com/index.php? R = test/index * was originally intended to access the test controller in the controller of the application and execute the index action. ** However, if a module is named test, there is an IndexController. ** according to the above Code, $ id = test is generated, $ route = index ** because this module exists in the search below, the index Controller under the test module is executed, * Instead of executing the index action of the test controller in the application */$ module = $ this-> getModule ($ id); if ($ module! = Null) {return $ module-> createController ($ route);} // If controller ing is specified in the controllerMap array, the controller if (isset ($ this-> controllerMap [$ id]) {$ controller = Yii :: createObject ($ this-> controllerMap [$ id], [$ id, $ this]); return [$ controller, $ route];} /** if $ route contains "/", that is, the original route is home/index/aa * $ id: home (not a module) * $ route: index/aa * since we know above that home is not a module, This Is The namespace (subdirectory), ** after the following processing, it is named * $ id: home/index Space (subdirectory) home index controller * $ route: aaa **/if ($ pos = strrpos ($ route ,'/'))! = False) {$ id. = '/'. substr ($ route, 0, $ pos); $ route = substr ($ route, $ pos + 1);}/** $ id: home/index * $ route: aaa */$ controller = $ this-> createControllerByID ($ id); if ($ controller = null & $ route! = '') {// If creation fails, add route as the id to create another $ controller = $ this-> createControllerByID ($ id. '/'. $ route); $ route = '';} return $ controller = null? False: [$ controller, $ route];}
In this function, $ id has two situations: one is with a namespace before, and the other is directly with a controller ID.
Public function createControllerByID ($ id) {if (! Preg_match ('% ^ [a-z0-9 \-_/] + $ %', $ id) {return null;}/** if $ id contains "/", the preceding directory is followed by the class **/$ pos = strrpos ($ id, '/'); if ($ pos = false) {$ prefix = ''; $ className = $ id;} else {$ prefix = substr ($ id, 0, $ pos + 1); $ className = substr ($ id, $ pos + 1);} // generates the Controller class IndexController $ className = str_replace ('','', ucwords (str_replace ('-','', $ className ))). 'controller'; // If a prefix (that is, a directory or namespace) exists, add the prefix to the class. Namespace $ className = ltrim ($ this-> controllerNamespace. '\\'. str_replace ('/', '\', $ prefix ). $ className, '\'); // if the class does not exist or the class name contains "-", an error occurs. if (strpos ($ className ,'-')! = False |! Class_exists ($ className) {return null;} // The following is the created class if (is_subclass_of ($ className, 'yii \ base \ controller ')) {return new $ className ($ id, $ this);} elseif (YII_DEBUG) {throw new InvalidConfigException ("Controller class must extend from \ yii \ base \ Controller. ") ;}else {return null ;}}
This process ends, and then the created controller executes the actions in it.
Public function runAction ($ route, $ params = []) {$ parts = $ this-> createController ($ route); if (is_array ($ parts )) {/** @ var Controller $ controller */list ($ controller, $ actionID) = $ parts; $ oldController = Yii ::$ app-> controller; Yii :: $ app-> controller = $ controller; // The controller executes the corresponding action $ result = $ controller-> runAction ($ actionID, $ params); Yii :: $ app-> controller = $ oldController; return $ result;} else {$ id = $ This-> getUniqueId (); throw new InvalidRouteException ('unable to resolve the request "'. ($ id = ''? $ Route: $ id. '/'. $ route ).'".');}}