• <rt id="vhKGd"><nav id="vhKGd"><link id="vhKGd"></link></nav></rt>

    1. <output id="vhKGd"><tr id="vhKGd"><optgroup id="vhKGd"><table id="vhKGd"></table></optgroup></tr></output>

          <area id="vhKGd"></area>

            tp5.1.38路由生成代码有bug

            浏览:1024 发布日期:2020/01/21
            5.0.0 - 严重 - 已关闭
            使用url('index/News/list',['group_name'=>'aaa','page'=>1]);时发现问题
            route.php 填写2下面2个路由 Route::rule('news/<group_name>/p-<page>', 'index/News/list');
             Route::rule('news/<group_name>', 'index/News/list');
            当参数只传group_name的时候,匹配后的路由为:
            www.test.com/aaa/p-<page>,原应该是:www.test.com/aaa
            如果上面路由顺序颠倒下,传2个参数的时候,生成的路由为:
            www.test.com/aaa/page/1,原应该是:www.test.com/aaa/p-1
            后来检查代码,是路由解析代码有bug;
            代码地址 thinkphp/library/think/Url.php:349  // 匹配路由地址
                public function getRuleUrl($rule, &$vars = [], $allowDomain = '')
                {
                    foreach ($rule as $item) {
                        list($url, $pattern, $domain, $suffix, $method) = $item;

                        if (is_string($allowDomain) && $domain != $allowDomain) {
                            continue;
                        }

                        if (!in_array($this->app['request']->port(), [80, 443])) {
                            $domain .= ':' . $this->app['request']->port();
                        }

                        if (empty($pattern)) {
                            return [rtrim($url, '?/-'), $domain, $suffix];
                        }

                        $type = $this->config['url_common_param'];

                        foreach ($pattern as $key => $val) {
                            if (isset($vars[$key])) {
                                $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? $vars[$key] : urlencode($vars[$key]), $url);
                                unset($vars[$key]);//原值被unset,外部foreach拿不到原值
                                $url    = str_replace(['/?', '-?'], ['/', '-'], $url);
                                $result = [rtrim($url, '?/-'), $domain, $suffix];
                            } elseif (2 == $val) {
                                $url    = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url);
                                $url    = str_replace(['/?', '-?'], ['/', '-'], $url);
                                $result = [rtrim($url, '?/-'), $domain, $suffix];
                            } else {
                                //未清空$result
                                break;
                            }
                        }

                        if (isset($result)) {
                            return $result;
                        }
                    }

                    return false;
                }
            问题处在内循环的foreach,
            问题一:第一个变量匹配成功后,第二个变量匹配失败,在最后的break;之前没有清空$result,出了内循环后会被return,
            问题二:$vars在内循环第一个参数被匹配到后参数时被清除,第二参数匹配失败,到外循环foreach时,参数$vars拿不到原始的参数,在之前的内循环中被unset()了
            评论(
            后面还有条评论,点击查看>>