PHP接收URL中文参数乱码,核心是统一UTF-8编码链路:确保前端用encodeURIComponent编码、PHP文件为UTF-8无BOM、响应头声明charset,优先通过$_SERVER['QUERY_STRING']手动解析,避免直接依赖已自动解码且可能错码的$_GET。

PHP 后台解码数据,核心就看来源和编码类型——不是所有“编码”都用 urldecode() 或 base64_decode() 一把梭。
收到前端传来的 URL 参数,中文乱码或 %E4%B8%AD%E6%96%87 怎么办
这是典型的 URL 编码(application/x-www-form-urlencoded),PHP 默认已自动解码 $_GET 和 $_POST(除非 php.ini 关闭了 enable_post_data_reading 或用了 php://input 手动读取)。
- 确认是否真没解:打印
$_GET['name']看输出是“中文”还是“%E4%B8%AD%E6%96%87”;如果是后者,说明你绕过了 PHP 自动解析,比如用file_get_contents('php://input')读原始体 - 手动解码用
urldecode(),不是rawurldecode()—— 前者兼容空格转成空格(+→),后者只处理%XX,适合application/json里嵌套的 URL 片段 - 注意字符集:解码后若仍是乱码,大概率是前端没设
Content-Type: application/x-www-form-urlencoded; charset=utf-8,或 HTML 表单缺<meta charset="utf-8">,PHP 解码本身不负责转码
接收 JSON 请求体,json_decode() 返回 null
常见于 fetch 或 axios 发送 Content-Type: application/json 的 POST 请求。PHP 不会自动解析它,$_POST 为空,必须手动读取并解码。
- 先读原始输入:
$raw = file_get_contents('php://input'); - 再解码:
$data = json_decode($raw, true);—— 第二个参数true返回关联数组,否则是对象 - 检查失败原因:
json_last_error()和json_last_error_msg(),90% 是前端发了带 BOM 的 UTF-8、多了一行换行、或字段值里混了不可见控制字符(如\u2028) - 别用
$_POST去取 JSON 数据,那是给表单用的;也别对$raw先urldecode(),JSON 体本身不是 URL 编码
Base64 字符串解码后是乱码或提示“Invalid base64”
Base64 解码失败通常不是函数问题,而是数据在传输中被二次处理过。
立即学习“PHP免费学习笔记(深入)”;
- 确认字符串长度是 4 的倍数,末尾补的
=没被截断或 URL 转义(比如+变成空格、/被当路径分隔符) - 如果来自 URL 查询参数(如
?token=SGVsbG8=),需先urldecode()再base64_decode(),因为+在 URL 中代表空格,但 Base64 的+是有效字符 - 解码后是二进制(如图片、加密密文),不要直接
echo;若期望是文本,检查原始编码(比如 Base64 包的是 UTF-8 字节,解出来就是 UTF-8 字符串) - 安全起见,加校验:
if (base64_decode($str, true) === false) { /* 处理非法输入 */ },第二个参数开启严格模式,拒绝含非法字符的字符串
POST 表单提交含文件,$_FILES 为空或 error=1
这不是“解码”问题,但常被误认为编码失败——实际是上传机制未触发或配置拦截。
-
$_FILES为空:检查 HTML 表单是否有enctype="multipart/form-data",缺了这个,文件根本不会发到服务端 -
error=1:对应UPLOAD_ERR_INI_SIZE,是php.ini的upload_max_filesize或post_max_size设得太小,和解码无关 - 文件内容本身不需要“解码”,
$_FILES['file']['tmp_name']就是已写入临时目录的原始字节,直接file_get_contents()或fopen()读即可 - 若前端对文件内容做了 Base64 编码再 POST(少见但存在),那才是走
php://input+base64_decode()流程,此时要自己处理边界和大小限制
最易忽略的一点:解码只是还原字节,不解决字符集错位。比如前端用 GBK 编码发来 URL 参数,PHP 用 UTF-8 解码,结果必乱——解码前得先知道原始编码,而现代 Web 应该统一用 UTF-8 并显式声明。



















