GET 表單或連結傳遞中文參數時,若未編碼直接放入 URL,伺服器接收後常出現亂碼(尤其 Apache + PHP 預設 ISO-8859-1 解碼)。本文說明 **`urlencode` / `urldecode`** 標準流程、`rawurlencode` 差異、JavaScript 配合、`http_build_query` 批次處理與現代框架自動處理機制。
<a href="list.php?plate=轄區動態">查看</a>
// 瀏覽器實際請求(視編碼而定):
// list.php?plate=%E8%BD%84%E5%8D%80%E5%8B%95%E6%80%81 (UTF-8)
// 或 list.php?plate=%B5%A5%B3%F6%B6%AF%B2%BB (Big5)
// PHP 接收 $_GET['plate'] 可能得到亂碼或截斷
<?php
$plate = '轄區動態';
$encoded = urlencode($plate); // 轉為 %E8%BD%84%E5%8D%80%E5%8B%95%E6%80%81
echo "<a href='list.php?plate=$encoded'>查看</a>";
<?php
$plate = urldecode($_GET['plate'] ?? '');
echo $plate; // 正確顯示:轄區動態
| 函式 | 空白編碼 | 符合標準 | 適用場景 |
|---|---|---|---|
urlencode | `+` (加號) | application/x-www-form-urlencoded | **表單 POST/GET 參數、舊系統相容** |
rawurlencode | `%20` | RFC 3986 (URI 標準) | **URL 路徑片段、現代 API、OAuth 簽名** |
urldecode | 解 `+` 為空白 | 配對 urlencode | 接收表單參數 |
rawurldecode | 不解 `+` | 配對 rawurlencode | 解析 URL 路徑、Header |
**建議**:**參數值一律用 `rawurlencode` / `rawurldecode`**(符合 URI 標準),除非對接舊系統要求 `+` 代表空白。
// 正確:encodeURIComponent (RFC 3986,對應 PHP rawurlencode)
const param = encodeURIComponent('轄區動態'); // "%E8%BD%84%E5%8D%80%E5%8B%95%E6%80%81"
fetch(`list.php?plate=${param}`)
// 錯誤:escape() (已棄用)、encodeURI() (不編碼 & = ? 等保留字元)
$params = [
'plate' => '轄區動態',
'page' => 2,
'sort' => 'desc',
];
// 預設使用 PHP_QUERY_RFC3986 (rawurlencode) - PHP 5.4+
$query = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
echo "list.php?$query";
// list.php?plate=%E8%BD%84%E5%8D%80%E5%8B%95%E6%80%81&page=2&sort=desc
GET 中文參數亂碼核心在於**「編碼/解碼雙方不一致」**。標準流程:**發送端 `rawurlencode` (JS `encodeURIComponent`) → 接收端 PHP 自動 `urldecode`(直接用 `$_GET`)**。專案統一 UTF-8、棄用手動 `urldecode`、善用 `http_build_query` 批次產生查詢字串,即可徹底消除亂碼。