Skip to content
This repository has been archived by the owner on Jan 4, 2020. It is now read-only.

3.2.4版本的路由失效 #531

Open
hepeichun opened this issue Oct 13, 2018 · 24 comments
Open

3.2.4版本的路由失效 #531

hepeichun opened this issue Oct 13, 2018 · 24 comments

Comments

@hepeichun
Copy link

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

@bigiot
Copy link

bigiot commented Oct 15, 2018

我的也有失效现象:
'URL_ROUTE_RULES'=>array(
'talk/:id\d' => 'Talk/talk',
'talkcate/:id\d' => 'Talk/category',
'mobile' => 'Index/mobile',
'donate' => 'Index/donate'
)
前两个的配置方法继续有效,后两个找不到控制器。

@hepeichun
Copy link
Author

我的也有失效现象:
'URL_ROUTE_RULES'=> array(
'talk /:id \ d'=>'Talk / talk',
'talkcate /:id \ d'=>'Talk / category',
'mobile'=> 'index / mobile',
'donate'=>'索引/捐赠'

前两个的配置方法继续有效,后两个找不到控制器。

坐等官方修复吧,手动无奈

@liu21st
Copy link
Member

liu21st commented Oct 19, 2018

静态路由规则应该统一在URL_MAP_RULES配置里面定义的

@blackpuppy
Copy link
Contributor

blackpuppy commented Nov 11, 2018

我也遇到同样的动态路由失效的问题,同样的无法加载控制器的错误。看3.2.4的9个commits3.2.5的3个commits,完全没有改到路由,但是框架路由的行为发生了变化。原来应用程序的代码可以正常工作,升级到3.2.4之后却不行了。查看了一下2015年10月8日3.2.3发布之后的commits,其实有很多改动,远不止上述的12个commits,路由的部分,比如Library/Think/Dispatcher.class.phpThinkPHP/Library/Think/Route.class.php都有比较大的变动。是否有相应的文档,说明这些框架的变化对应用程序有哪些影响,需要相应作出什么样的改动呢?

谢谢!

@blackpuppy
Copy link
Contributor

blackpuppy commented Nov 12, 2018

@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官方已经不维护了,所以要靠社区中还在使用该版本的我们自己来承担这个责任了。

谢谢!

@blackpuppy
Copy link
Contributor

blackpuppy commented Nov 18, 2018

之前对路由的修正仍不完整。又经过几天折磨人的调试,终于使我近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。希望大家帮助测试,以覆盖更多不同的使用用例。

谢谢!

@blackpuppy
Copy link
Contributor

blackpuppy commented Nov 18, 2018

@liu21st 我已经提交了PR #535,请检查,如需改进请告知。
另外,建议对框架的修改,必须分外谨慎,因为框架是很多用户开发应用的基础,一旦引入了哪怕很小的错误,也有可能影响很多人。尤其是3.2已经过了维护生命周期,更多的可能是对安全性等不得不做的更新,核心团队对其关注度肯定不如正在开发和使用的5.0等版本,相比而言3.2也缺乏单元测试等比较好的质量验证手段,使得任何改动都更难验证。
谢谢!

@blackpuppy
Copy link
Contributor

又有一些新的对路由的修正,详见PR #535
关于路由的单元测试,可见示例项目blackpuppy/thinkblog

@cnjackven
Copy link

这个路由的调整应用公告一下,同是3.2.*的版本更新的时候应该考虑下兼容问题,更新后直接大部分路由干不起也不科学啊

@hepeichun
Copy link
Author

又有一些新的对路由的修正,详见PR #535
关于路由的单元测试,可见示例项目blackpuppy/thinkblog

谢谢

@hepeichun
Copy link
Author

还发现一个问题,我将路由定义在子模块配置文件,这样就失效了,需要将路由定义到主配置文件

@hepeichun hepeichun reopened this Dec 28, 2018
@blackpuppy
Copy link
Contributor

blackpuppy commented Dec 28, 2018

@jdkysq

还发现一个问题,我将路由定义在子模块配置文件,这样就失效了,需要将路由定义到主配置文件

有测试用例吗?有空的时候,我也试一下。我用过不同的模块,但没用过子模块。

@hepeichun
Copy link
Author

hepeichun commented Dec 28, 2018

@jdkysq

还发现一个问题,我将路由定义在子模块配置文件,这样就失效了,需要将路由定义到主配置文件

有测试用例吗?有空的时候,我也试一下。我用过不同的模块,但没用过子模块。

我在Application/Plugin/Conf/config.php里面添加路由

'URL_ROUTER_ON' => true,
'URL_ROUTE_RULES'=>array(
'Plugin'=>'Plugin/Load/index'
),
发现无法调用

将上面的代码放入到Application/Common/Common/function.php里面问题解决。

@blackpuppy
Copy link
Contributor

@jdkysq
参考3.2的文档路由定义

启用路由

要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),并且在应用(或者模块)配置文件中开启路由:

不知道你说的子模块,是3.2支持的功能吗?为什么我在3.2的文档里没有搜到?

@hepeichun
Copy link
Author

@jdkysq
参考3.2的文档路由定义

启用路由
要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),并且在应用(或者模块)配置文件中开启路由:

不知道你说的子模块,是3.2支持的功能吗?为什么我在3.2的文档里没有搜到?

子模块,Plugin是我自己添加的

@blackpuppy
Copy link
Contributor

blackpuppy commented Dec 28, 2018

@jdkysq 你所谓的”子模块“,从你的代码看,就是模块。比如子目录,强调是目录下的目录,前面才加个”子“,子模块,亦如此。但是从你提供的代码看,Plugin模块并不在另一个模块中,叫”子模块“是不妥的。

路由解析,要根据路由规则来确定模块(以及控制器和操作等),所以无法先加载模块中定义的路由规则,路由规则只能写在公用模块Common中。用你的例子来说明,公用模块Common的配置肯定要加载,但是在解析路由确定模块之前,并不知道是否需要Plugin模块,所以不会加载Plugin模块中的配置。因此,在路由解析时,Plugin模块中定义的路由规则就不起作用,只有公用模块Common中的路由规则才起作用。这是我的理解。

我怀疑,文档中说的,可以在非公共模块的配置文件中用URL_ROUTER_ON配置开启路由,或者用URL_ROUTE_RULES来定义路由规则,是否真的可行。如果可行,希望作者(@liu21st)能够提供这样的例子。

@hepeichun
Copy link
Author

hepeichun commented Dec 28, 2018

@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模块的配置文件做的正则路由才成功。
现在我们已经将静态路由移到公共模块的配置文件,一切正常。

@blackpuppy
Copy link
Contributor

blackpuppy commented Dec 28, 2018

我只是表达我的看法,谈不上指正,互相交流。

我是从3.2.3开始用的,发现在非公用模块中配置路由规则就不行,所以都放在公用模块的配置中了。从你经历的情况来看,一些修订号的升级都有很大的影响。如果按照语义化版本来看,次版本号和修订号的变更不应该包含不兼容的变化,只有主版本号的变化才是不兼容的变化。另外,这种路由解析的重大变化,的确是缺乏明确充分的文档说明和升级指导。

我用的情况很有限,做的修复很可能也没有考虑到所有可能的情况,所以希望有更多的用户测试不同的用例。

另外,URL_ROUTE_RULES是动态路由,你说的是静态路由URL_MAP_RULES吗?

@blackpuppy
Copy link
Contributor

blackpuppy commented Jan 24, 2019

我发现从 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"
                }
            }
        }
    ],
    ...

@blackpuppy
Copy link
Contributor

@liu21st 不知道你是不是没有注意到这个问题,再次提醒一下。如前所述,用composer安装的3.2.5版本不是源码的3.2.5版本,不包含我对路由的修复,不知道是不是需要再发布一个版本?

@liu21st
Copy link
Member

liu21st commented Oct 27, 2019

@blackpuppy 任何改动都是要发布新版本的,3.2版本已经过了维护生命周期,官方已经不再维护,请及时更新至5.0或者5.1版本。所以目前只能自行修复了~

@blackpuppy
Copy link
Contributor

@liu21st 可是通过composer发布的3.2.5版本不是真正的3.2.5版本,这会误导3.2.5的使用者,如何自行修复呢?

@liu21st
Copy link
Member

liu21st commented Oct 28, 2019

3.2.5版本发布之后 才修正的这个。官方不维护更新了 ,就自己直接修改源码就行了 反正你也不会更新官方包了,或者自己fork一个单独更新

@blackpuppy
Copy link
Contributor

blackpuppy commented Oct 28, 2019

可是3.2.5包含的9个commits包含了这些修复,这与事实不符,难道不应该再发布一个3.2.6吗?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants