在 Web 開發中,URL 參數傳遞時必須對特殊字元進行編碼,PHP 提供了四組核心函式:urlencode() / urldecode() 與 rawurlencode() / rawurldecode()。兩者差異在於空格處理與 RFC 標準遵循度,本文詳細解析其行為差異、適用場景,並提供中文亂碼解決方案與 Unicode 解碼進階技巧。
| 函式 | 空格編碼 | 遵循標準 | 適用場景 |
|---|---|---|---|
urlencode() | +(加號) | application/x-www-form-urlencoded | 表單 POST、查詢字串 |
rawurlencode() | %20 | RFC 3986 (舊 RFC 1738) | Path、HTTP Header、FTP URL |
urldecode() | 將 + 還原為空格 | 配合 urlencode | 解析查詢字串 |
rawurldecode() | 保留 + 不轉換 | 配合 rawurlencode | 解碼 Path 片段 |
<?php
$userInput = '張三 & 李四';
$url = "search.php?q=" . urlencode($userInput);
// 輸出: search.php?q=%E5%BC%B5%E4%B8%89+%26+%E6%9D%8E%E5%9B%9B
echo '<a href="' . htmlentities($url) . '">搜尋</a>';
?>
關鍵點:輸出至 HTML 屬性時,務必再包一層 htmlentities() 防止 & 被瀏覽器誤解為實體字元。
<?php
$path = 'sales and marketing/Miami';
$url = "https://api.example.com/department/" . rawurlencode($path);
// 輸出: https://api.example.com/department/sales%20and%20marketing%2FMiami
?>
<?php
$pwd = 'foo @+%/';
$url = "ftp://user:" . rawurlencode($pwd) . "@ftp.example.com/file.txt";
?>
encodeURIComponent()(JS)對應 PHP rawurldecode()。urldecode()。<?php
$decoded = urldecode($encodedStr); // 取得 UTF-8 字串
if ('UTF-8' !== mb_internal_encoding()) {
$decoded = mb_convert_encoding($decoded, mb_internal_encoding(), 'UTF-8');
}
?>
%uXXXX Unicode 逃逸格式解碼部分舊系統或 JavaScript escape() 產生 %u4E2D%u6587 格式,標準解碼函式無法處理,需自訂函式:
<?php
function utf8RawUrlDecode($source) {
$decoded = '';
$len = strlen($source);
for ($pos = 0; $pos < $len; $pos++) {
$ch = $source[$pos];
if ($ch !== '%') {
$decoded .= $ch;
continue;
}
$pos++;
if ($pos >= $len) break;
$next = $source[$pos];
if ($next === 'u') { // %uXXXX
$pos++;
$hex = substr($source, $pos, 4);
$pos += 3; // 迴圈再 +1
$code = hexdec($hex);
$decoded .= mb_convert_encoding('' . $code . ';', 'UTF-8', 'HTML-ENTITIES');
} else { // %XX
$hex = $next . $source[$pos + 1];
$pos += 1;
$decoded .= chr(hexdec($hex));
}
}
return $decoded;
}
// 測試
echo utf8RawUrlDecode('%u4E2D%u6587'); // 輸出: 中文
?>
urlencode() + htmlentities() 輸出 HTML。rawurlencode()。escape()/unescape():改用 encodeURIComponent()/decodeURIComponent()。掌握編解碼細節,能有效避免參數截斷、簽名驗證失敗、中文亂碼等棘手問題,是後端 API 開發的基本功。