首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP urlencode() 與 rawurlencode() 差異深度解析:RFC 3986 vs 應用表單標準

     編輯:PHP 相關知識

核心差異一覽

特性urlencode()rawurlencode()
標準依據application/x-www-form-urlencoded (HTML 表單)RFC 3986 (URI 標準)
空格編碼+ (加號)%20
保留字元-_. 不編碼-_.~ 不編碼 (波浪號差異)
適用場景POST 表單、URL 查詢字串值URL 路徑、Header、OAuth 簽名

編碼範圍對照

<?php
$test = "Hello World! @#$/中文";
echo "urlencode: " . urlencode($test) . "\n";
// Hello+World%21+%40%23%24%2F%E4%B8%AD%E6%96%87

echo "rawurlencode: " . rawurlencode($test) . "\n";
// Hello%20World%21%20%40%23%24%2F%E4%B8%AD%E6%96%87
?>

實戰場景選擇指南

場景一:建構 URL 查詢字串(推薦 urlencode)

<?php
$params = [
    'q' => 'PHP 教學',
    'page' => 2,
    'tag' => 'web+dev'
];
$query = http_build_query($params); // 內部使用 urlencode
echo "https://example.com/search?$query";
// https://example.com/search?q=PHP+%E6%95%99%E5%AD%B8&page=2&tag=web%2Bdev
?>

場景二:建構 URL 路徑段落(必須 rawurlencode)

<?php
$username = "john doe";
$path = "/user/" . rawurlencode($username) . "/profile";
// /user/john%20doe/profile
?>

場景三:OAuth 1.0 簽名基礎字串(強制 rawurlencode)

<?php
function oauth_encode($str) {
    return str_replace('%7E', '~', rawurlencode($str)); // RFC 5849 要求 ~ 不編碼
}

$base = "GET&" . oauth_encode("https://api.example.com/resource") . "&" .
        oauth_encode("oauth_consumer_key=key&oauth_nonce=123");
// 簽名計算...
?>

場景四:JavaScript 互通(前端 encodeURIComponent = rawurlencode)

<?php
// PHP 接收 JS 傳來的參數
$js_encoded = $_GET['data']; // JS: encodeURIComponent("中文") -> "%E4%B8%AD%E6%96%87"
$decoded = rawurldecode($js_encoded); // 正確解碼
// 若用 urldecode() 會將 %20 解為空格,但 + 會解為空格,導致實際 + 字元遺失
?>

解碼函數對應

編碼函數解碼函數空格處理
urlencode()urldecode()+ → 空格
rawurlencode()rawurldecode()%20 → 空格,+ 保持 +

常見錯誤與修正

  • 錯誤:urlencode($path_segment) → 空格變 +,伺服器解析為查詢字串分隔符
  • 錯誤:雙重編碼 urlencode(urlencode($str))
  • 修正:路徑用 rawurlencode,查詢值用 urlencode,整體 URL 用 http_build_query 組裝

遷移建議

新專案優先使用 rawurlencode,除非明確處理 application/x-www-form-urlencoded 表單資料。PSR-7 UriInterface 實作內部皆採 RFC 3986。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved