用了模块映射之后,关于U和控制其中$this->redirect方法生成链接的分享

浏览:1263 发布日期:2016/01/08 分类:技术分享 关键字: 映射 模块映射 MAP U方法生成问题
不知道有多少伙伴与我有同样困惑(我用的是TP3.2.3版本,核心框架下载下来没有做任何更改的情况下):
我的问题:

上面图片是我的config文件,此文件中开启了URL_MODULE_MAP模块映射,当时发现这个功能的时候,很欢喜,瞬间感觉TP强大啊,人性化啊。
但是刚刚进入项目,就发现问题了

后台首页做登录校验的时候,我们常用判断 没登陆就跳回登录页面。
因为做了模块映射了,所以我访问后台的地址是
http://域名/Admin如果没做模块映射,上图中的$this->redirect('Sign/login')方法一点问题没有,直接跳回登录页。
可是现在开启了模块映射,问题来了,当没有登录的时候,跳转回去的url是这样的

怎么回事?我设置了映射模块为Admin了,按理说,访问http://域名/Admin的时候,没登陆应该跳转回http://域名/Admin/Sign/login啊,怎么会是跳转回上图的链接呢。于是我傻兮兮的把上图连接中的Winsystem_Administrator_ManagementPlatform_Index手动改成Admin,总算进入登录页了,可是验证码出问题了,

又怎么回事?不用说,肯定是链接问题,看看我验证码获取的链接,在login.html模版中,是这样的

打开强大的火狐,看看这个验证码地址

万恶!又变成Winsystem_Administrator_ManagementPlatform_Index了,为什么不是Admin??
然后一番查资料,哦,看到了有大神说 模块映射之后,可以用MODULE_ALIAS来获取别名,试了一下,果然可以,看下图



哟,竟然真的可以了,变过来了,但是注意 上面最后一个图,链接是 /admin/Sign/Captcha,注意这个/admin是小写首字母哦,呃,windows上倒还无所谓啦,linux上,恐怕……,所以,我改进了一下,用了ucfirst(),可以了

到此,感觉是解决了呢,也的确解决了之前的问题,梳理一下,怎么解决的呢?
就是在用U方法生成连接时,写成U( ucfirst(MODULE_ALIAS ,'/控制器名/操作名')),或者$this->redirect( ucfirst(MODULE_ALIAS.'/控制器名/操作名') )
这样是解决了,可是我怎么总感觉别扭,难道每次写U方法都要这样写?当然可以,可是我个人觉得在之前没做映射的时候,习惯了U('控制器/操作')这种方式,强迫症惹的祸。所以我决定再寻找一下。终于,十五分钟后,理想变成现实了。
/**
* 在这里申明一下:我所发现的这个问题,以及我的解决办法,仅限个人参考,
* 如果官方已经有了解决办法,请根据官方介绍为准。本人是刚好遇到且没
* 查到方法,所以做了相应更改
*/
我通过源码追踪到U方法的源代码,发现了问题(当然对我来说叫问题,可能官方有好的解决办法,我没发现而已)

在U方法的发源地:ThinkPHP/Common/function.php文件的第976行,有这样一句判断if($maps = C('URL_MODULE_MAP')) {
                if($_module = array_search(strtolower($var[$varModule]),$maps)){
                    $var[$varModule] = $_module;
                }
            }
经过跟踪,发现,如果开启了模块映射之后,if($maps = C('URL_MODULE_MAP')) 能进去,可是if($_module = array_search(strtolower($var[$varModule]),$maps))就进不去了。进过打印到页面上对比,发现
我在配置文件中,进行的映射是  'URL_MODULE_MAP'=>array('admin'=>'Winsystem_Administrator_ManagementPlatform_Index'),  if($_module = array_search(strtolower($var[$varModule]),$maps))中,strtolower($var[$varModule])变成了全部小写了,这里判断进不去,所以下面的$module还是原来的Winsystem_Administrator_ManagementPlatform_Index,而不是映射后的Admin 所以,斗胆改了一下,  
if($maps = C('URL_MODULE_MAP')) {
             if($_module = array_search($var[$varModule],$maps)){
                    $var[$varModule] = ucfirst($_module);
                }
            }
这样小小改动,就完全可以实现直接使用U('控制器/方法') 和 $this->redirect('控制器/方法')去生成映射后的url了,不需要在家MODULE_ALIAS
到此我的改动就结束了,说了这么大一片,其实就是一个小小的改动。
但是有的朋友可能会说 在配置文件中,使用URL_MODULE_MAP =>array('admin'=>'winsystem_administrator_managementplatform_index')这样全部小写就好了啊,但是我试过了,这样不行,会出现访问http://域名/Admin 报不存在的错,
如果还有朋友说 可以在配置文件中开启 大小写不敏感,我也试过,也看到网上很多人都在说 一旦关闭了debug模式,就会出现错误,唉本人研究还不深,有待学习,如果有朋友有好的方法,或者更详细的知识,请留言告知,不胜感激。
我也想尊重框架,尽量不改动框架核心源码,可是这里我也找不到方法了。
最佳答案
评论( 相关
后面还有条评论,点击查看>>