tp5.1.38路由生成代码有bug

浏览:932 发布日期:2019/11/12
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()了
评论(
后面还有条评论,点击查看>>