本文实例讲述了Yii2创建控制器(createController)方法。分享给大家供大家参考,具体如下:

yii中创建控制器的是在application中的request通过UrlManager解析得出路由信息的,然后再由yii\base\Module中的

public function runAction($route, $params = [])

方法来创建控制器,最后由控制器再执行相应的动作。

首先得明确,Yii中的路由分三种情况:

第一种是带有模块的(module id/controller id/action id),

第二种是带有命名空间(子目录)的(sub dir)/controller id/action id)

第三种是只有控制器和动作的(controller id/action id)

这三个有优先顺序,所以在创建控制器的时候,也是先查看是否是模块类型的路由,如果是,则获取这个模块,再由这个模块来创建控制器

接着再判断是否是第二种带有命名空间的。

public function createController($route)

{

//如果路由为空,则使用默认的路由

if ($route === '') {

$route = $this->defaultRoute;

}

// double slashes or leading/ending slashes may cause substr problem

//去掉首尾的反斜杠(“/”),如果路由中包含有“//”,则返回false创建失败。

$route = trim($route, '/');

if (strpos($route, '//') !== false) {

return false;

}

/*

* 路由分三种情况,

* 一种是带模块id的(module id/controller id/action id),

* 一种是有命名空间(子目录)的(sub dir)/controller id/action id)

* 一种是只有控制器和动作的(controller id/action id)

* 所以在这里要根据第一个“/”分隔成两部分,$id和$route信息,

*/

if (strpos($route, '/') !== false) {

list ($id, $route) = explode('/', $route, 2);

} else {

$id = $route;

$route = '';

}

// module and controller map take precedence

/*

* 查看这个id是否是模块,如果是模块,则再用这个模块来创建控制器。

* 所以,在如果一个控制器的名称和模块名称重复的话会优先创建模块里面的控制器。

*

* 如果有url: http://www.yii2.com/index.php?r=test/index

* 本来是打算访问application中的控制器里面的test控制器,执行index动作的。

*

* 然而如果有个模块的名字为test,里面有个IndexController

*

* 根据上面会生成$id=test,$route=index

*

* 由于在下面查找存在这个模块,所以会执行这个test模块下面的index控制器,

* 而不会执行application里面的test控制器的index动作

*/

$module = $this->getModule($id);

if ($module !== null) {

return $module->createController($route);

}

//如果在controllerMap数组中指定了控制器映射,会优先根据这个里面的映射来创建控制器

if (isset($this->controllerMap[$id])) {

$controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);

return [$controller, $route];

}

/*

* 如果这个时候$route中还有“/”,也就是说原来的路由为home/index/aa

* $id:home(不是模块)

* $route:index/aa

* 由于经过上面得知home不为模块,所以这个为命名空间(子目录),

*

* 再经过下面处理后为

* $id:home/index 命名空间(子目录)home下面的index控制器

* $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 !== '') {

//如果创建失败,再加上route作为id再次创建

$controller = $this->createControllerByID($id . '/' . $route);

$route = '';

}

return $controller === null ? false : [$controller, $route];

}

在这个函数中$id就有两种情况,一种是前面带有命名空间的,一种是直接就一个控制器ID的。

public function createControllerByID($id)

{

if (!preg_match('%^[a-z0-9\\-_/]+$%', $id)) {

return null;

}

/*

* 如果$id中有“/”,则前面的为目录,后面的为类

*

*/

$pos = strrpos($id, '/');

if ($pos === false) {

$prefix = '';

$className = $id;

} else {

$prefix = substr($id, 0, $pos + 1);

$className = substr($id, $pos + 1);

}

//生成控制器的类IndexController

$className = str_replace(' ', '', ucwords(str_replace('-', ' ', $className))) . 'Controller';

//如果有前缀(也就是有目录、命名空间),则在类前面加上命名空间

$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');

//如果类不存在,或者类名称包含“-”,则出错,

if (strpos($className, '-') !== false || !class_exists($className)) {

return null;

}

//下面就是创建类了

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;

}

}

这个过程就结束了,然后再由创建出来的控制器执行它里面的动作

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;

//控制器执行相应的动作

$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) . '".');

}

}

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

php怎么创建控制器,Yii2创建控制器(createController)方法详解相关推荐

  1. 塞尔之光的树心旋转机关_塞尔之光攻略心得_塞尔之光怎么创建人物 塞尔之光角色创建方法详解-公共游戏资源网...

    死后这个剑鞘是父亲留给我的,他说这个剑鞘是看护着国际和平的钥匙,尽管不知道是什么意思,但 个树心图纹使命,现已对好了便是过不了塞尔之光梦魇城堡怎样过 梦魇城堡攻略流程介绍答:塞尔之光梦魇城堡攻略流程 ...

  2. linux oracle 用户创建,LINUX下Oracle数据库用户创建方法详解

    本文实例分析了LINUX下Oracle数据库用户创建方法.分享给大家供大家参考,具体如下: 1)登录linux,以oracle用户登录(如果是root用户登录的,登录后用 su - oracle命令切 ...

  3. python process 函数_Python Process创建进程的2种方法详解

    前面介绍了使用 os.fork() 函数实现多进程编程,该方法最明显的缺陷就是不适用于 Windows 系统.本节将介绍一种支持 Python 在 Windows 平台上创建新进程的方法. Pytho ...

  4. python创建双链表_Python双链表原理与实现方法详解

    本文实例讲述了Python双链表原理与实现方法.分享给大家供大家参考,具体如下: Python实现双链表 文章目录 Python实现双链表 单链表与双链表比较 双链表的实现 定义链表节点 初始化双链表 ...

  5. linux在vi创建文件,Linux下创建文本文件(vi/vim命令使用详解)

    vi test.txt 或者 vim test.txt 再或者 touch test.txt vim是vi的升级版,指令更多,功能更强. 下面是收集的vim用法,当在vim里面要实现退出,首先要做的是 ...

  6. thinkphp3.1.3 getshell_C# / VB.NET 在PPT中创建、编辑PPT SmartArt图形的方法详解_C#教程...

    本文介绍通过C#和程序代码来创建和编辑PPT文档中的SmartArt图形.文中将分两个操作示例来演示创建和编辑结果. 使用工具:Spire.Presentation for .NET hotfix 5 ...

  7. 【沐风老师】3dMax创建缝线插件StitchLines使用方法详解

    3dMax创建缝线插件使用方法详解 3dMax创建缝线插件StitchLines,一键生成车缝线建模,该脚本与可编辑多边形.可编辑样条线或 编辑多边形修改器一起使用,创建一条样条曲线(车缝线),它将以 ...

  8. navicat mysql 计划任务_navicat创建MySql定时任务的方法详解

    navicat创建MySql 定时任务详解 事件(event)是MySQL在相应的时刻调用的过程式数据库对象.一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的" ...

  9. Java设计模式之五大创建型模式(附实例和详解)

    一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥 ...

最新文章

  1. maven 强制更新_Android App内部更新Library的方法
  2. Activiti数据库
  3. OpenFileDialog 和 FolderBrowserDialog
  4. sqlmap 相关参数
  5. UI debug mode
  6. Asterisk 并发量到100后就出现拨打电话挂机问题
  7. C++:17---函数指针
  8. python批量合并csv_如何在Python中通过多个列合并两个CSV文件
  9. 网页幻灯片切换动画特效源码
  10. hbaseRegion的划分
  11. 实验7 OpenGL光照
  12. ESPNet: Efficient Spatial Pyramid of Dilated Convolutions for Semantic Segmentation(自动驾驶领域轻量级模型)
  13. Ubuntu18.04中安装virtualenv和virtualenvwrapper
  14. jQuery图片LightBox插件 点击图片放大 支持移动手机
  15. Linux 在线词典
  16. iPad mini2 Vieux降级ios10.3.3 问题解决合集
  17. 什么是云计算?让我来告诉你~
  18. Javascript 书写规范
  19. 数据集生成期间遇到的BUG及解决方案
  20. 【路径规划】基于matlab蚁群优化遗传算法机器人栅格地图最短路径规划【含Matlab源码 1581期】

热门文章

  1. MYSQL 更改初始 ROOT 密码
  2. 没有微信和QQ,用记事本也能在线聊天
  3. obj[key]和0bj.['key']
  4. Python turtle画图库画姓名实例(Python入门)
  5. 在一台电脑上如何安装两个JDK,并实现自由切换
  6. 调试 debugging
  7. 【NOIP 2016 提高组】蚯蚓
  8. python 基于metpy计算位涡平流项(水平)
  9. AT command
  10. win7打开计算机有嘟嘟提示音,大神研习win7系统电脑开机经常发出嘟嘟哔哔的声音的解决技巧...