urlencode将空格编码为+,rawurlencode统一用%20;对外API、路径参数、签名原文必须用rawurlencode,仅表单提交时可用urlencode,编解码需严格配对。

urlencode 和 rawurlencode 都会编码,但空格处理不同
这是最常踩坑的地方:用 urlencode 编码后的空格变成 +,而 rawurlencode 统一用 %20。HTTP 协议规范里,query string 中的空格本应编码为 %20,+ 是表单提交(application/x-www-form-urlencoded)的约定,并非通用 URL 编码规则。
常见错误现象:urlencode('hello world') 返回 hello+world,后端收到时若直接按 RFC 3986 解码(比如用 Node.js 的 decodeURIComponent),+ 不会被转成空格,结果变成 hello world → hello+world → hello world(错乱)。
- 对外提供 API 参数、拼接 RESTful 路径、生成签名原文时,一律用
rawurlencode - 只有在手动构造
application/x-www-form-urlencoded请求体(比如 curl -d)时,才考虑urlencode -
rawurlencode编码结果和 JavaScript 的encodeURIComponent行为一致;urlencode对应的是encodeURI(但不完全等价,慎用对比)
中文路径或查询参数必须用 rawurlencode,否则 Nginx/Apache 可能 400
现代 Web 服务器默认只接受符合 RFC 3986 的 URI,遇到未编码的中文或 urlencode 生成的 + 在 path 段(非 query)时,很可能直接拒掉请求,返回 400 Bad Request —— 这不是 PHP 的问题,是服务器层拦截了。
使用场景:生成带中文的下载链接、REST API 的资源 ID(如 /api/user/张三)、重写规则中的目标路径。
- 路径段(path)里的中文、特殊字符,必须用
rawurlencode,例如:rawurlencode('张三')→%E5%BC%A0%E4%B8%89 - 不要对整个 URL 调用
rawurlencode,那会把:、/、?等也编码,彻底破坏结构 - 如果用了 Laravel 或 Symfony 路由,框架通常自动处理,但自定义重写或跳转时仍需手动编码
urldecode 和 rawurldecode 不能混用,否则中文变乱码
编码和解码必须配对:用 rawurlencode 编的,就得用 rawurldecode 解;用 urlencode 编的,才用 urldecode。PHP 的 urldecode 会把 + 当空格,rawurldecode 则完全不管 +,只处理 %xx。
典型错误:前端用 encodeURIComponent 发请求(等价于 PHP rawurlencode),后端却用 urldecode($_GET['q']),导致中文参数解出来是乱码。
- 检查来源:JS 侧是
encodeURIComponent还是encodeURI?对应 PHP 就选rawurldecode或urldecode -
$_GET和$_POST已被 PHP 自动urldecode过(针对+和%xx),一般不用再解;但$_SERVER['REQUEST_URI']是原始值,需手动rawurldecode - 别依赖
mb_convert_encoding补救,那是掩盖编码不匹配的问题
性能差异几乎可以忽略,别为“快一点”选错函数
两者底层都走相同的编码逻辑,仅在空格处理分支有微小差别,百万次调用差距不到 1ms。选哪个,只取决于你遵循哪套规范。
容易被忽略的点:有些老代码用 urlencode 处理路径,上线后在某些 CDN 或 WAF 上被拦截,排查时才发现是 + 不被接受——这种问题不会报 PHP 错误,而是静默失败或 403/400。
复杂点在于:你得清楚当前字符串最终会进哪个上下文——是 HTTP header?query string?URL path?还是 form body?每个位置的编码要求其实不同,不能一招鲜吃遍天。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











