中文URL编码需统一UTF-8:GET参数用urlencode()(空格→+),路径段用rawurlencode()(空格→%20,不编码/等保留符);http_build_query()自动编码更安全;$_GET已解码,勿重复解码。

中文参数直接拼进URL会出错,必须编码;但用错函数或漏设UTF-8,解码后照样是乱码。
urlencode() 和 rawurlencode() 选哪个?
两者都对中文有效,但空格处理不同:urlencode() 把空格转成 +,rawurlencode() 转成 %20。浏览器和PHP的 $_GET 都能正确识别 + 为空格,所以日常构造查询参数用 urlencode() 更省心。
但如果你在拼 URL 路径(比如 /api/v1/users/张三),就得用 rawurlencode()——它不碰 /、? 这类保留字符,而 urlencode() 会把路径里的斜杠也放过去,导致路由解析失败。
- GET 参数值(
?q=搜索关键词)→ 用urlencode() - URL 路径段(
/user/姓名)→ 用rawurlencode() - 调用第三方 REST API 时,看文档要求:要
%20就用rawurlencode(),要兼容表单提交就用urlencode()
为什么 urldecode() 有时解不出中文?
不是函数坏了,而是整个链路没统一 UTF-8。PHP 的 urldecode() 只负责把 %E4%BD%A0 这种字节还原出来,它不管这串字节该按什么编码显示。如果页面响应头没设 Content-Type: text/html; charset=utf-8,或者 HTML 里缺 ,浏览器就会用默认编码(比如 GBK)去解读 UTF-8 字节,结果就是 。
- 确保 PHP 文件本身是 UTF-8 无 BOM 格式保存
- 脚本开头加
header('Content-Type: text/html; charset=utf-8'); - HTML 中写
- 数据库连接也要设 UTF-8(如
$mysqli->set_charset('utf8mb4'))
多个参数一起拼,别手写 urlencode()
手动拼 "?name=" . urlencode($name) . "&city=" . urlencode($city) 容易漏、难维护,还容易忘掉编码。直接用 http_build_query():
$params = ['name' => '李四', 'city' => '上海', 'tag' => ['php', 'web']]; $url = 'https://example.com/search?' . http_build_query($params);
它自动对每个值调用 urlencode(),支持嵌套数组,且生成的格式标准(tag[0]=php&tag[1]=web)。注意:键名不会被编码,所以自己保证键名是合法 ASCII 字符即可。
接收端不用手动 urldecode()
PHP 在收到 GET 请求时,已经把 $_GET 里的所有值用 urldecode() 处理过了。你直接取 $_GET['name'] 就是原始中文字符串,再调一次 urldecode() 反而会出错(比如把 % 当作编码前缀二次解码)。
唯一要手动解码的场景是:你从请求体、HTTP 头、或自定义字段里拿到的是已编码的字符串(比如某个 API 返回的 "encoded_name": "%E5%BC%A0%E4%B8%89"),这时才需要 urldecode() 或 rawurldecode()。
最常被忽略的一点:编码函数只管字节转换,不管语义。如果原始字符串里混了不同编码(比如 GBK 和 UTF-8 拼在一起),urlencode() 照样编码,但解出来还是乱码——得先用 mb_convert_encoding() 统一转成 UTF-8 再处理。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











