解決 PHP 使用 file_get_contents()、cURL、wget 等請求含中文路徑 URL 時遭遇 404 錯誤的問題:使用 parse_url() 解析 URL 結構,對 path 部分逐段 rawurlencode() 編碼,重組合法 URL。
<?php
$url = 'https://example.com/搜尋/關鍵字/頁面.html';
// 直接請求會導致 404,因為中文未編碼
$content = file_get_contents($url); // 失敗
?>
<?php
function urlConvert($url) {
$parts = parse_url($url);
if (!isset($parts['path'])) return $url;
// 路徑分段編碼(保留 / 分隔符)
$pathSegments = explode('/', $parts['path']);
$encodedSegments = array_map('rawurlencode', $pathSegments);
$newPath = implode('/', $encodedSegments);
// 重組 URL(保留 scheme, host, query, fragment 等)
$newUrl = $parts['scheme'] . '://' . $parts['host'] . $newPath;
if (isset($parts['query'])) $newUrl .= '?' . $parts['query'];
if (isset($parts['fragment'])) $newUrl .= '#' . $parts['fragment'];
return $newUrl;
}
// 使用
$url = 'https://example.com/搜尋/關鍵字/頁面.html';
$encodedUrl = urlConvert($url);
// 結果:https://example.com/%E6%90%9C%E5%B0%8B/%E9%97%9C%E9%8D%B5%E5%AD%97/%E9%A0%81%E9%9D%A2.html
$content = file_get_contents($encodedUrl); // 成功
?>
| 步驟 | 函數 | 說明 |
|---|---|---|
| 1. 解析 URL | parse_url() | 分離 scheme, host, path, query, fragment |
| 2. 分段路徑 | explode('/', $path) | 逐段處理,避免編碼 / 分隔符 |
| 3. 編碼各段 | rawurlencode() | RFC 3986 標準,空格編為 %20(非 +) |
| 4. 重組路徑 | implode('/', ...) | 還原 / 分隔符 |
| 5. 重組完整 URL | 字串拼接 | 保留 query、fragment 原樣(已編碼) |
<?php
$str = '中文 測試';
echo rawurlencode($str); // %E4%B8%AD%E6%96%87%20%E6%B8%AC%E8%A9%A6 (空格→%20)
echo urlencode($str); // %E4%B8%AD%E6%96%87+%E6%B8%AC%E8%A9%A6 (空格→+)
?>
URL 路徑必須用 rawurlencode();urlencode() 適用於 application/x-www-form-urlencoded 表單資料(query string)。
<?php
function urlConvertSafe($url) {
$parts = parse_url($url);
$path = $parts['path'] ?? '';
// 僅編碼未編碼的段落(簡易檢測:含 % 視為已編碼)
$segments = array_map(function($seg) {
return (strpos($seg, '%') !== false) ? $seg : rawurlencode($seg);
}, explode('/', $path));
$parts['path'] = implode('/', $segments);
// 重組...
return $parts['scheme'] . '://' . $parts['host'] . $parts['path']
. (isset($parts['query']) ? '?' . $parts['query'] : '')
. (isset($parts['fragment']) ? '#' . $parts['fragment'] : '');
}
?>
正確處理 URL 編碼是網路程式開發的基本功,parse_url() + rawurlencode() 是標準解法。