当前位置: 首页> 最新文章列表> 结合 parse_url 和 urlencode 正确处理编码

结合 parse_url 和 urlencode 正确处理编码

gitbox 2025-05-26

在日常开发中,开发者经常需要处理包含中文参数的 URL。由于中文字符在 URL 中不能直接使用,必须经过编码处理,否则可能导致解析错误或请求失败。PHP 提供了多个与 URL 相关的函数,其中 parse_url 用于解析 URL,而 urlencode 用于对字符串进行 URL 编码。如何正确地结合这两个函数,成为处理中文参数时的关键。

本文将通过示例,讲解如何结合使用 parse_urlurlencode,正确地处理包含中文参数的 URL。

一、问题背景

假设我们有一个 URL:

https://gitbox.net/search?q=测试&lang=zh

该 URL 中的查询参数包含中文“测试”。如果我们直接传递这个 URL 给某些接口,可能因为未编码导致识别失败。而如果全量使用 urlencode 对整个 URL 编码,又会导致结构混乱,比如冒号、斜线、问号等也被错误编码。

因此,我们需要精确地对“值”进行编码,而不是对整个 URL。

二、使用 parse_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

最后,我们将处理后的各部分重新拼接成一个完整 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,而应当:

  1. 使用 parse_url 拆解 URL;

  2. 使用 parse_str 分离 query 部分;

  3. 对每个参数值使用 urlencode 编码;

  4. 使用 http_build_query 重新构造 query;

  5. 拼接成完整 URL。

这种方式既保留了 URL 结构,也确保了参数的正确编码,避免了中文字符导致的问题。