public function testBuildNameRoute() { Route::get(['name', 'blog/:id'], 'index/blog'); $this->assertEquals([['blog/:id', ['id' => 1], null]], Route::name('name')); Config::set('url_html_suffix', 'shtml'); $this->assertEquals('/blog/10.shtml', Url::build('name?id=10')); }
/** * URL生成 支持路由反射 * @param string $url 路由地址 * @param string|array $vars 参数(支持数组和字符串)a=val&b=val2... ['a'=>'val1', 'b'=>'val2'] * @param string|bool $suffix 伪静态后缀,默认为true表示获取配置值 * @param boolean|string $domain 是否显示域名 或者直接传入域名 * @return string */ public static function build($url = '', $vars = '', $suffix = true, $domain = false) { if (false === $domain && Config::get('url_domain_deploy')) { $domain = true; } // 解析URL if (0 === strpos($url, '[') && ($pos = strpos($url, ']'))) { // [name] 表示使用路由命名标识生成URL $name = substr($url, 1, $pos - 1); $url = 'name' . substr($url, $pos + 1); } $info = parse_url($url); $url = !empty($info['path']) ? $info['path'] : ''; if (isset($info['fragment'])) { // 解析锚点 $anchor = $info['fragment']; if (false !== strpos($anchor, '?')) { // 解析参数 list($anchor, $info['query']) = explode('?', $anchor, 2); } if (false !== strpos($anchor, '@')) { // 解析域名 list($anchor, $domain) = explode('@', $anchor, 2); } } elseif (strpos($url, '@')) { // 解析域名 list($url, $domain) = explode('@', $url, 2); } // 解析参数 if (is_string($vars)) { // aaa=1&bbb=2 转换成数组 parse_str($vars, $vars); } if ($url) { $rule = Route::name(isset($name) ? $name : $url . (isset($info['query']) ? '?' . $info['query'] : '')); if (is_null($rule) && isset($info['query'])) { $rule = Route::name($url); // 解析地址里面参数 合并到vars parse_str($info['query'], $params); $vars = array_merge($params, $vars); unset($info['query']); } } if (!empty($rule) && ($match = self::getRuleUrl($rule, $vars))) { // 匹配路由命名标识 $url = $match[0]; if (!empty($match[1])) { $domain = $match[1]; } } elseif (!empty($rule) && isset($name)) { throw new \InvalidArgumentException('route name not exists:' . $name); } else { if (isset($info['query'])) { // 解析地址里面参数 合并到vars parse_str($info['query'], $params); $vars = array_merge($params, $vars); } // 路由标识不存在 直接解析 $url = self::parseUrl($url, $domain); } // 检测URL绑定 $type = Route::getBind('type'); if ($type) { $bind = Route::getBind($type); if (0 === strpos($url, $bind)) { $url = substr($url, strlen($bind) + 1); } } // 还原URL分隔符 $depr = Config::get('pathinfo_depr'); $url = str_replace('/', $depr, $url); // URL后缀 $suffix = in_array($url, ['/', '']) ? '' : self::parseSuffix($suffix); // 锚点 $anchor = !empty($anchor) ? '#' . $anchor : ''; // 参数组装 if (!empty($vars)) { // 添加参数 if (Config::get('url_common_param')) { $vars = urldecode(http_build_query($vars)); $url .= $suffix . '?' . $vars . $anchor; } else { foreach ($vars as $var => $val) { if ('' !== trim($val)) { $url .= $depr . $var . $depr . urlencode($val); } } $url .= $suffix . $anchor; } } else { $url .= $suffix . $anchor; } // 检测域名 $domain = self::parseDomain($url, $domain); // URL组装 $url = $domain . (self::$root ?: Request::instance()->root()) . '/' . ltrim($url, '/'); return $url; }