在日常開發中,開發者經常需要處理包含中文參數的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 結構,也確保了參數的正確編碼,避免了中文字符導致的問題。