在日常开发中,开发者经常需要处理包含中文参数的 URL。由于中文字符在 URL 中不能直接使用,必须经过编码处理,否则可能导致解析错误或请求失败。PHP 提供了多个与 URL 相关的函数,其中 parse_url 用于解析 URL,而 urlencode 用于对字符串进行 URL 编码。如何正确地结合这两个函数,成为处理中文参数时的关键。
本文将通过示例,讲解如何结合使用 parse_url 和 urlencode,正确地处理包含中文参数的 URL。
假设我们有一个 URL:
https://gitbox.net/search?q=测试&lang=zh
该 URL 中的查询参数包含中文“测试”。如果我们直接传递这个 URL 给某些接口,可能因为未编码导致识别失败。而如果全量使用 urlencode 对整个 URL 编码,又会导致结构混乱,比如冒号、斜线、问号等也被错误编码。
因此,我们需要精确地对“值”进行编码,而不是对整个 URL。
首先,我们用 parse_url 分解出 URL 的各个组成部分:
$url = 'https://gitbox.net/search?q=测试&lang=zh';
$parsed = parse_url($url);
print_r($parsed);
输出结果如下:
Array
(
[scheme] => https
[host] => gitbox.net
[path] => /search
[query] => q=测试&lang=zh
)
通过这个解析结果,我们可以得到原始的查询字符串,但注意,这里的 query 是未经处理的原始形式。
我们可以利用 parse_str 将 query 部分转换为关联数组,然后对值进行编码:
parse_str($parsed['query'], $queryParams);
foreach ($queryParams as $key => $value) {
$queryParams[$key] = urlencode($value);
}
现在,$queryParams 中的每个值都被正确编码为 URL 安全格式。
接下来,我们需要将这些参数重新拼接成查询字符串:
$encodedQuery = http_build_query($queryParams);
这会生成如下字符串:
q=%E6%B5%8B%E8%AF%95&lang=zh
注意:http_build_query 在编码值时,默认会将空格转为加号(+),如果你希望空格用 %20 表示,可以加上第二个参数:
$encodedQuery = http_build_query($queryParams, '', '&', PHP_QUERY_RFC3986);
最后,我们将处理后的各部分重新拼接成一个完整 URL:
$finalUrl = $parsed['scheme'] . '://' . $parsed['host'] . $parsed['path'] . '?' . $encodedQuery;
echo $finalUrl;
输出结果为:
https://gitbox.net/search?q=%E6%B5%8B%E8%AF%95&lang=zh
现在,该 URL 中的中文参数已经被安全编码,适用于任何浏览器或 HTTP 请求库。
为了方便重用,可以将上述逻辑封装成一个函数:
function encodeUrlQuery($url) {
$parsed = parse_url($url);
if (!isset($parsed['query'])) {
return $url;
}
parse_str($parsed['query'], $queryParams);
foreach ($queryParams as $key => $value) {
$queryParams[$key] = urlencode($value);
}
$encodedQuery = http_build_query($queryParams, '', '&', PHP_QUERY_RFC3986);
$result = $parsed['scheme'] . '://' . $parsed['host'];
if (isset($parsed['path'])) {
$result .= $parsed['path'];
}
$result .= '?' . $encodedQuery;
return $result;
}
使用方法:
$url = 'https://gitbox.net/search?q=测试&lang=zh';
echo encodeUrlQuery($url);
输出:
https://gitbox.net/search?q=%E6%B5%8B%E8%AF%95&lang=zh
在 PHP 中处理包含中文参数的 URL 时,不能直接对整个 URL 使用 urlencode,而应当:
使用 parse_url 拆解 URL;
使用 parse_str 分离 query 部分;
对每个参数值使用 urlencode 编码;
使用 http_build_query 重新构造 query;
拼接成完整 URL。
这种方式既保留了 URL 结构,也确保了参数的正确编码,避免了中文字符导致的问题。