两者对中文编码结果完全一致,差异仅在于空格(urlencode→+,rawurlencode→%20)、波浪号等特殊字符处理;rawurlencode严格遵循RFC 3986,适用于URL路径和现代API,urlencode仅适用于老旧表单提交。

rawurlencode() 和 urlencode() 编码中文时结果差异在哪
两者对中文字符本体(如“姓名”“搜索关键词”)的编码结果完全一致,都是 %E5%A7%93%E5%90%8D 这类 UTF-8 字节序列的百分号编码;真正区别出现在**非中文字符混入时**——尤其是空格、波浪号 ~、点号 .、斜杠 / 等 URL 路径/查询符敏感字符。
例如:$str = "张三 搜索~test";
-
urlencode($str)→%E5%BC%A0%E4%B8%89+%E6%90%9C%E7%B4%A2~test(空格变+,~未编码) -
rawurlencode($str)→%E5%BC%A0%E4%B8%89%20%E6%90%9C%E7%B4%A2%7Etest(空格变%20,~变%7E)
什么时候必须用 rawurlencode()
只要字符串会拼进 URL 的 路径段(path) 或作为 查询参数值(query value)直接参与路由/鉴权/签名,就该用 rawurlencode()。现代 API(如微信、高德、Stripe)和 RESTful 接口基本都严格遵循 RFC 3986,把 + 当普通字符处理,不认作空格。
常见踩坑场景:
立即学习“PHP免费学习笔记(深入)”;
- 构造类似
/api/v1/user/张三的路径,用urlencode()会导致服务器 404(因为/user/%E5%BC%A0%E4%B8%89+中的+被当字面量,而非空格) - 调用带签名的接口,参数含空格或
~,但签名前用了urlencode(),而服务端用rawurldecode()验签,导致哈希不匹配 - 生成下载链接的
download属性值,如<a download="报告 2025.pdf">,空格必须是%20才能被浏览器正确识别
urlencode() 唯一还值得用的场景
仅限向**老旧 PHP 表单提交目标**传参,且对方明确要求 application/x-www-form-urlencoded 格式(比如某些内网 CMS 的 POST 接口、遗留的 $_POST 处理逻辑)。此时空格必须为 +,否则接收方用 urldecode() 解不出原意。
但注意:即使在这种场景下,也不能对整个 URL 调用 urlencode(),否则会把 :、//、? 全部编码,导致请求发不出去。只编码参数值本身。
中文文件名下载和 header 中的 Content-Disposition 怎么编
浏览器对 Content-Disposition 头里的 filename 和 filename* 字段解析规则不统一,稳妥做法是双写:
-
filename用rawurlencode()编码(兼容老 IE) -
filename*用rawurlencode()+UTF-8''前缀(标准写法)
示例:
header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"; filename*=UTF-8\'\'' . rawurlencode($filename));
这里必须用 rawurlencode(),因为 filename* 的规范明确要求按 RFC 3986 编码,urlencode() 产生的 + 会被部分浏览器忽略或解析失败。
实际开发中,rawurlencode() 应该成为默认选择;urlencode() 只在对接明确文档化要求表单编码格式的旧系统时才临时启用。别让一个空格或波浪号,拖垮整个请求链路。



















