<a href="list.php?plate=轄區動態" charset="utf-8" target="main">[查看轄區動態]</a>
// list.php 接收到:$_GET['plate'] = "轄區動怿" (亂碼)
原因:瀏覽器將中文按頁面編碼(UTF-8)進行 URL 編碼傳輸,但伺服器解碼時若編碼不一致,或直接在 URL 中硬編碼中文,極易產生亂碼。
<?php
$plate = '轄區動態';
$encoded = urlencode($plate); // %E8%BD%84%E5%8D%80%E5%8B%95%E6%80%81
?>
<a href="list.php?plate=<?php echo $encoded; ?>" target="main">[查看]</a>
<?php
// 必須最先輸出,確保瀏覽器以 UTF-8 解析頁面
header("Content-Type: text/html; charset=utf-8");
if (isset($_GET['plate'])) {
$plate = urldecode($_GET['plate']); // 還原為 "轄區動態"
echo $plate;
}
?>
| 函數 | 用途 | 範例輸出 |
|---|---|---|
urlencode($str) | 將字串編碼為 URL 安全格式(空格變 +,非英數字元變 %XX) | urlencode('中文') → '%E4%B8%AD%E6%96%87' |
urldecode($str) | 還原 urlencode 編碼的字串 | urldecode('%E4%B8%AD%E6%96%87') → '中文' |
rawurlencode($str) | RFC 3986 標準編碼(空格變 %20),適合路徑段 | rawurlencode('a b') → 'a%20b' |
rawurldecode($str) | 對應 rawurlencode 解碼 | — |
<?php
$params = [
'foo' => '值含有空格 & 特殊字元',
'bar' => '另一個值'
];
// 1. 逐個參數編碼
$query = http_build_query($params);
// foo=%E5%80%BC%E5%90%AB%E6%9C%89%E7%A9%BA%E6%A0%BC+%26+%E7%89%B9%E6%AE%8A%E5%AD%97%E5%85%83&bar=%E5%8F%A6%E4%B8%80%E5%80%8B%E5%80%BC
// 2. 整體再用 htmlentities 防止 HTML 屬性注入
$safeUrl = 'api.php?' . htmlentities($query, ENT_QUOTES, 'UTF-8');
?>
<a href="<?php echo $safeUrl; ?>">安全連結</a>
href="?q=中文" → 依賴瀏覽器編碼行為,不可靠header('Content-Type: ... charset=utf-8') → 瀏覽器可能用 Big5/GBK 解碼頁面,導致二次亂碼urlencode / rawurlencode → 路徑段請用 rawurlencode,查詢字串用 urlencode/http_build_query$request->input('key')),內建處理編碼發送端 urlencode() → 傳輸 → 接收端 urldecode() + 統一 UTF-8 Header 是解決 GET 中文亂碼的鐵律。現代框架已自動處理,但理解底層機制對除錯、對接舊系統、API 設計至關重要。