3.2.4版本的路由失效
我正尝试将程序由3.2.2升级到3.2.4,中间发现我们的路由规则失效

我的也有失效现象: 'URL_ROUTE_RULES'=>array( 'talk/:id\d' => 'Talk/talk', 'talkcate/:id\d' => 'Talk/category', 'mobile' => 'Index/mobile', 'donate' => 'Index/donate' ) 前两个的配置方法继续有效,后两个找不到控制器。
我的也有失效现象: 'URL_ROUTE_RULES'=> array( 'talk /:id \ d'=>'Talk / talk', 'talkcate /:id \ d'=>'Talk / category', 'mobile'=> 'index / mobile', 'donate'=>'索引/捐赠' ) 前两个的配置方法继续有效,后两个找不到控制器。
坐等官方修复吧,手动无奈
静态路由规则应该统一在URL_MAP_RULES配置里面定义的
我也遇到同样的动态路由失效的问题,同样的无法加载控制器的错误。看3.2.4的9个commits和3.2.5的3个commits,完全没有改到路由,但是框架路由的行为发生了变化。原来应用程序的代码可以正常工作,升级到3.2.4之后却不行了。查看了一下2015年10月8日3.2.3发布之后的commits,其实有很多改动,远不止上述的12个commits,路由的部分,比如Library/Think/Dispatcher.class.php和ThinkPHP/Library/Think/Route.class.php都有比较大的变动。是否有相应的文档,说明这些框架的变化对应用程序有哪些影响,需要相应作出什么样的改动呢?
谢谢!
@jdkysq @bigiot
经过一番调试,发现对框架做如下改动,可以修复我的问题: ThinkPHP/Library/Think/Route.class.php第61行由:
if ($matches = self::checkUrlMatch($rule, $args, $regx)) {
改为:
$matches = self::checkUrlMatch($rule, $args, $regx);
if ($matches !== false) {
道理也很简单,我猜测私有方法checkUrlMatch()返回false表示动态路由未匹配成功,而在返回值的判断上,误把空数组也当成未匹配成功。
我还要测试一下,看这样是否适用于我所有的近300个动态路由(有web,也有API)。如果的确如此,我会提交一个PR。可能的话,希望大家也可以帮我测试一下,看是否能解决问题,另外是否还有其他问题。
既然3.2官方已经不维护了,所以要靠社区中还在使用该版本的我们自己来承担这个责任了。
谢谢!
之前对路由的修正仍不完整。又经过几天折磨人的调试,终于使我近300个动态路由(有web,也有API)又能够在3.2.5下正常工作了,通过单元测试。下面是我对框架的完整修正(包括之前提到的),只涉及一个文件ThinkPHP/Library/Think/Route.class.php:
ThinkPHP/Library/Think/Route.class.php第61行由:
if ($matches = self::checkUrlMatch($rule, $args, $regx)) {
改为:
$matches = self::checkUrlMatch($rule, $args, $regx);
if ($matches !== false) { // 严格检查false才表示动态路由未匹配成功
ThinkPHP/Library/Think/Route.class.php第440行由:
// 如果值在排除的名单里
if (in_array($var, $val[2])) {
改为:
// 如果值在排除的名单里
if (is_array($val[2]) && in_array($var, $val[2])) {
在ruleCache(...)中读取路由配置应当避免改变路由定义顺序,因为顺序也会影响路由的解析。ThinkPHP/Library/Think/Route.class.php第273行由:
// 动态路由
$result[1] = C('URL_ROUTE_RULES');
if (!empty($result[1])) {
foreach ($result[1] as $rule => $route) {
改为:
// 动态路由
$result[1] = [];
$dynamicRoutes = C('URL_ROUTE_RULES');
if (!empty($dynamicRoutes)) {
foreach ($dynamicRoutes as $rule => $route) {
并删除ThinkPHP/Library/Think/Route.class.php第350-351行。
我会提交一个PR。希望大家帮助测试,以覆盖更多不同的使用用例。
谢谢!
@liu21st 我已经提交了PR #535,请检查,如需改进请告知。 另外,建议对框架的修改,必须分外谨慎,因为框架是很多用户开发应用的基础,一旦引入了哪怕很小的错误,也有可能影响很多人。尤其是3.2已经过了维护生命周期,更多的可能是对安全性等不得不做的更新,核心团队对其关注度肯定不如正在开发和使用的5.0等版本,相比而言3.2也缺乏单元测试等比较好的质量验证手段,使得任何改动都更难验证。 谢谢!
又有一些新的对路由的修正,详见PR #535。 关于路由的单元测试,可见示例项目blackpuppy/thinkblog。
这个路由的调整应用公告一下,同是3.2.*的版本更新的时候应该考虑下兼容问题,更新后直接大部分路由干不起也不科学啊
还发现一个问题,我将路由定义在子模块配置文件,这样就失效了,需要将路由定义到主配置文件
@jdkysq
还发现一个问题,我将路由定义在子模块配置文件,这样就失效了,需要将路由定义到主配置文件
有测试用例吗?有空的时候,我也试一下。我用过不同的模块,但没用过子模块。
@jdkysq
还发现一个问题,我将路由定义在子模块配置文件,这样就失效了,需要将路由定义到主配置文件
有测试用例吗?有空的时候,我也试一下。我用过不同的模块,但没用过子模块。
我在Application/Plugin/Conf/config.php里面添加路由
'URL_ROUTER_ON' => true, 'URL_ROUTE_RULES'=>array( 'Plugin'=>'Plugin/Load/index' ), 发现无法调用
将上面的代码放入到Application/Common/Common/function.php里面问题解决。
@jdkysq 参考3.2的文档路由定义:
启用路由
要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),并且在应用(或者模块)配置文件中开启路由:
不知道你说的子模块,是3.2支持的功能吗?为什么我在3.2的文档里没有搜到?
@jdkysq 参考3.2的文档路由定义:
启用路由 要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),并且在应用(或者模块)配置文件中开启路由:
不知道你说的子模块,是3.2支持的功能吗?为什么我在3.2的文档里没有搜到?
子模块,Plugin是我自己添加的
@jdkysq 你所谓的”子模块“,从你的代码看,就是模块。比如子目录,强调是目录下的目录,前面才加个”子“,子模块,亦如此。但是从你提供的代码看,Plugin模块并不在另一个模块中,叫”子模块“是不妥的。
路由解析,要根据路由规则来确定模块(以及控制器和操作等),所以无法先加载模块中定义的路由规则,路由规则只能写在公用模块Common中。用你的例子来说明,公用模块Common的配置肯定要加载,但是在解析路由确定模块之前,并不知道是否需要Plugin模块,所以不会加载Plugin模块中的配置。因此,在路由解析时,Plugin模块中定义的路由规则就不起作用,只有公用模块Common中的路由规则才起作用。这是我的理解。
我怀疑,文档中说的,可以在非公共模块的配置文件中用URL_ROUTER_ON配置开启路由,或者用URL_ROUTE_RULES来定义路由规则,是否真的可行。如果可行,希望作者(@liu21st)能够提供这样的例子。
@jdkysq 你所谓的”子模块“,从你的代码看,就是模块。比如子目录,强调是目录下的目录,前面才加个”子“,子模块,亦如此。但是从你提供的代码看,
Plugin模块并不在另一个模块中,叫”子模块“是不妥的。路由解析,要根据路由规则来确定模块(以及控制器和操作等),所以无法先加载模块中定义的路由规则,路由规则只能写在公用模块
Common中。用你的例子来说明,公用模块Common的配置肯定要加载,但是在解析路由确定模块之前,并不知道是否需要Plugin模块,所以不会加载Plugin模块中的配置。因此,在路由解析时,Plugin模块中定义的路由规则就不起作用,只有公用模块Common中的路由规则才起作用。这是我的理解。我怀疑,文档中说的,可以在非公共模块的配置文件中用
URL_ROUTER_ON配置开启路由,或者用URL_ROUTE_RULES来定义路由规则,是否真的可行。如果可行,希望作者(@liu21st)能够提供这样的例子。
谢谢指正。
tp3.2.2是可以在非公共模块中配置路由的,我们最初用的3.2.2,就只这样写的。而且反复测试发现3.2.2的路由也是有问题的。
TP3.2.2手册中的
'my' => 'Member/myinfo', // 静态地址路由
写法在TP3.2.2中是无法使用的,目前您参加修复的这个版本是可以用的。
最后我们测试在plugin模块的配置文件做的正则路由才成功。
现在我们已经将静态路由移到公共模块的配置文件,一切正常。
我只是表达我的看法,谈不上指正,互相交流。
我是从3.2.3开始用的,发现在非公用模块中配置路由规则就不行,所以都放在公用模块的配置中了。从你经历的情况来看,一些修订号的升级都有很大的影响。如果按照语义化版本来看,次版本号和修订号的变更不应该包含不兼容的变化,只有主版本号的变化才是不兼容的变化。另外,这种路由解析的重大变化,的确是缺乏明确充分的文档说明和升级指导。
我用的情况很有限,做的修复很可能也没有考虑到所有可能的情况,所以希望有更多的用户测试不同的用例。
另外,URL_ROUTE_RULES是动态路由,你说的是静态路由URL_MAP_RULES吗?
我发现从 https://packagist.org/packages/topthink/thinkphp 下载的 3.2.5 并不包换我对路由的修正,GitHub上的 tag v3.2.5 同样不对。难道不能更新 packagist.org 上已经发布的版本吗?还是要发布一个新的版本,比如 3.2.6,才行?
现在我只能在用 Composer 安装时,使用 GitHub 上的 master 分支,需要在 composer.json中增加下面这段:
...
"repositories": [
{
"type": "package",
"package": {
"name": "topthink/thinkphp",
"version": "3.2.5",
"source": {
"url": "https://github.com/top-think/thinkphp",
"type": "git",
"reference": "master"
}
}
}
],
...
@liu21st 不知道你是不是没有注意到这个问题,再次提醒一下。如前所述,用composer安装的3.2.5版本不是源码的3.2.5版本,不包含我对路由的修复,不知道是不是需要再发布一个版本?
@blackpuppy 任何改动都是要发布新版本的,3.2版本已经过了维护生命周期,官方已经不再维护,请及时更新至5.0或者5.1版本。所以目前只能自行修复了~
@liu21st 可是通过composer发布的3.2.5版本不是真正的3.2.5版本,这会误导3.2.5的使用者,如何自行修复呢?
3.2.5版本发布之后 才修正的这个。官方不维护更新了 ,就自己直接修改源码就行了 反正你也不会更新官方包了,或者自己fork一个单独更新
可是3.2.5包含的9个commits包含了这些修复,这与事实不符,难道不应该再发布一个3.2.6吗?