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路由不转换的原因及解决方法的主要内容,如果未能解决你的问题,请参考以下文章

PHP Thinkphp中开启debug 报错,是啥原因?

详谈php ip2long 出现负数的原因及解决方法

技术分享 DNS解析不生效的原因及解决方法

ThinkPHP5只让路由对index作用,不对admin作用。多模块多入口方式隐藏后台地址及路由冲突解决方案

thinkphp toArray 不能使用问题解决,及bind的使用

192.168.1.1进不去的原因及解决方法