ThinkPHP路由不转换的原因及解决方法
Posted 春哥爱分享
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThinkPHP路由不转换的原因及解决方法相关的知识,希望对你有一定的参考价值。
随着互联网的发展,网站开发技术日新月异。而Thinkphp作为一款流行的PHP开发框架之一,也在不断地吸纳更多的开发者来使用。然而,有时候我们在使用过程中会遇到一些问题,比如ThinkPHP路由不转换的问题。本文将详细介绍这个问题以及解决方法。
一、问题描述
在我们使用ThinkPHP进行开发时,有时会遇到这样的情况:当我们进行一些路由操作时,页面并未跳转至我们所期望的界面。
例如,我们希望通过URL“www.example.com/home/do”来访问“HomeController.php”中的“do”方法,但我们实际上却无法访问到此方法。同时,我们发现并没有报错信息出现,这就让我们无从下手。
二、原因分析
在ThinkPHP中,路由是通过URL后缀进行匹配的。如果在我们的URL中没有使用任何后缀,那么ThinkPHP将认为我们要访问的方法是控制器中的默认方法(默认方法名一般为“index”)。
例如,我们使用URL“www.example.com/home/index”时,就会默认访问“HomeController.php”中的“index”方法。
而当我们使用URL“www.example.com/home/do”时,由于没有使用任何后缀,ThinkPHP就会认为我们要访问的是“index”方法,同时由于“do”方法并不存在于控制器中,所以就会导致页面访问失败。
三、解决方法
1.使用“/”后缀
我们可以在URL后加上“/”,这样就可以避免出现路由不匹配的问题。例如,我们可以使用URL“www.example.com/home/do/”来访问“HomeController.php”中的“do”方法。
同时,我们在使用ThinkPHP进行开发时,推荐在配置文件config.php中将URL后缀设置为“/”,这样可以避免出现路由不转换的问题。
2.修改路由规则
我们也可以通过修改路由规则来解决问题。
首先,在我们的路由配置文件中(一般为route.php),我们可以将路由规则定义为:
return [
‘home/do/[:id]’ => ‘home/[:action]’,
];
这样,我们就可以通过URL“www.example.com/home/do/1”来访问“HomeController.php”中的“do”方法,并在URL中传递一个id参数。
四、总结
在使用ThinkPHP进行开发时,出现路由不转换的问题可能会让我们感到十分不便。但通过本文所介绍的两种解决方法,我们可以轻松地解决这个问题。在我们的开发过程中,需要充分了解ThinkPHP的路由规则,并且按照规范进行开发,这样才能更好地运用ThinkPHP进行网站开发
ThinkPHP5只让路由对index作用,不对admin作用。多模块多入口方式隐藏后台地址及路由冲突解决方案
用伪静态,把文章的路径设置成qiyet.cn/category1/category2/id.html 这样的格式。其中,涉及到两个参数,分类和id.于是,
遇到一个全动态路由设置的问题,问了很多人都没人解决,还是知乎上人才众多,竟然给解决了,就是绑定模块,加一个判断,我的路由配置局部代码如下:
switch(strtolower(BIND_MODULE))
case 'index':
// index模块路由定义
Route::rule(':cate/:id','index/goods/index');
Route::get('<name>/<id>','index/goods/index',[],['name'=>'[a-zA-Z]+','id'=>'\\d+']);//推荐使用这个格式,以上的格式容易冲突
break;
case 'admin':
// admin模块路由定义
break;
default:
代码真是简洁又优雅,为了向作者致敬,写入原文来源地址:https://zhuanlan.zhihu.com/p/134238563
如果你的路由规则比较特殊,可以在路由定义的时候使用组合变量。
例如:
Route::get('item-<name>-<id>','product/detail',[],['name'=>'\\w+','id'=>'\\d+']);
组合变量的优势是路由规则中没有固定的分隔符,可以随意组合需要的变量规则,例如路由规则改成如下一样可以支持:
Route::get('item<name><id>','product/detail',[],['name'=>'[a-zA-Z]+','id'=>'\\d+']);
Route::get('item@<name>-<id>','product/detail',[],['name'=>'\\w+','id'=>'\\d+']);
如果需要使用可选变量,则可以使用:
Route::get('item-<name><id?>','product/detail',[],['name'=>'[a-zA-Z]+','id'=>'\\d+']);
关于define(BIND_MODULE)的定义问题
define(BIND_MODULE)这个定义在哪个文件里面?
另外,为了以后方便查找和供后来人参考,摘抄备份如下:
我们在应用ThinkPHP5进行系统开发时,为了巩固后台安全,常常利用多入口机制来隐藏后台地址,在此以index和admin两个模块举例说明具体实现步骤及问题解决方案:
1:建立后台入口文件 如 admin.php,内容为:
<?php
// 定义应用目录
define('APP_PATH', __DIR__ . '/application/');
// 绑定当前入口文件到admin模块
define('BIND_MODULE','admin');
// 加载框架基础文件
require __DIR__ . '/thinkphp/start.php';
2:在配置文件config.php设置:
<?php
// 禁止访问模块
'deny_module_list' => ['common','admin'],
来禁止admin模块访问。
3:但在实际开发时,发现多模块多入口情况下,全局路由可能会同时影响index和admin模块,比如路由定义:
<?php
Route::rule('product/:id', 'index/Product/read');
Route::rule('product', 'index/Product/index');
实测中发现如果admin模块中也有product控制器及product控制器中有index方式,会报错:模块不存在:如下图
鉴于此,试图网上搜索TP5的路由按模块配置的解决方案,有改源码的,有利用路由分组,有截取URL按条件设置路由的等等,结果尝试了都不太好用,在此给出的解决方案是:
在index入口文件中显式绑定index模块:
<?php
// 绑定当前入口文件到index模块
define('BIND_MODULE','index');
这样,前台绑定index,后台绑定admin,我们就可以利用常量BIND_MODULE进行路由按模块定义:
<?php
switch(strtolower(BIND_MODULE))
case 'index':
// index模块路由定义
Route::rule('product/:id', 'index/Product/read');
Route::rule('product', 'index/Product/index');
break;
case 'admin':
// admin模块路由定义
break;
default:
经测试,解决后台地址隐藏及路由分模块定义同时没有发现系统异常。
以上是关于ThinkPHP路由不转换的原因及解决方法的主要内容,如果未能解决你的问题,请参考以下文章
ThinkPHP5只让路由对index作用,不对admin作用。多模块多入口方式隐藏后台地址及路由冲突解决方案