
本文详解为何 php 无法直接通过 $_post 或 $_request 获取 jquery 发送的 multipart/form-data 格式 put 请求数据,并提供兼容 formdata 的可靠解析方案。
本文详解为何 php 无法直接通过 $_post 或 $_request 获取 jquery 发送的 multipart/form-data 格式 put 请求数据,并提供兼容 formdata 的可靠解析方案。
在使用 jQuery 的 $.ajax() 向 PHP 后端发送 PUT 请求时,若采用 FormData 对象(如 new FormData(form))并设置 contentType: false 和 processData: false,请求体将自动以 multipart/form-data 编码发送——这与 POST 表单上传行为一致。但关键问题在于:PHP 原生不支持自动解析 multipart/form-data 格式的 PUT 请求体,因此 php://input 流中读取到的是原始二进制内容(含边界符 ----WebKitFormBoundary...),而非 URL-encoded 字符串,直接对它调用 parse_str() 会导致解析失败,出现乱码和键名丢失(如你看到的 "------WebKitFormBoundary..." 残留),进而引发 Undefined array key "id" 错误。
✅ 正确做法是:区分请求编码类型,对 multipart/form-data 使用 $_FILES + $_POST(需绕过 HTTP 方法限制),或改用 application/x-www-form-urlencoded 编码。
方案一:推荐 —— 改为 x-www-form-urlencoded 编码(最简洁可靠)
修改前端 AJAX,让 FormData 被序列化为标准表单字符串:
$('#bewerkGebruikerForm').on('submit', function(event) {
event.preventDefault();
const formData = new FormData(this);
// ✅ 将 FormData 转为 URL-encoded 字符串(支持 PUT)
const urlEncoded = new URLSearchParams(formData).toString();
$.ajax({
url: 'http://localhost/P08/hoornhek/api/gebruiker.php',
type: 'PUT', // 注意:jQuery 中应大写 'PUT',小写 'put' 可能被转为 POST
data: urlEncoded,
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8', // 显式声明
success: function(response) {
if (response.success) {
$('#bewerkGebruikerModal').hide();
window.location.reload();
} else {
showErrors(response.errors);
}
},
error: function(xhr) {
const errorMsg = xhr.responseJSON?.errors || 'Server error';
showErrors(errorMsg);
}
});
});
后端 PHP 即可安全使用 php://input 解析:
case "PUT":
// ✅ 仅适用于 application/x-www-form-urlencoded 请求
parse_str(file_get_contents("php://input"), $_PUT);
// 验证关键字段存在性(避免 Notice)
$id = $_PUT['id'] ?? null;
$naam = $_PUT['naam'] ?? '';
$email = $_PUT['email'] ?? '';
if (!$id) {
http_response_code(400);
echo json_encode(['success' => false, 'errors' => ['id is required']]);
exit;
}
// 执行业务逻辑
updateGebruiker($id, $naam, $email, /* ... */);
echo json_encode(['success' => true]);
break;
方案二:支持 multipart/form-data —— 手动解析(复杂,仅必要时用)
若必须上传文件(如头像),则需保留 multipart/form-data。此时 PHP 无法通过 php://input 读取(该流在 multipart 请求中为空),而应借助临时文件机制:
case "PUT":
// ⚠️ 重要:PHP 不会自动填充 $_POST 或 $_FILES for PUT → 需模拟
if ($_SERVER['CONTENT_TYPE'] === 'multipart/form-data') {
// 利用临时文件 + move_uploaded_file 逻辑(需配合前端设置 boundary)
// 更稳妥做法:改用 POST + _method=PUT(Laravel 风格)或统一用 POST 处理更新
http_response_code(405);
echo json_encode(['success' => false, 'errors' => ['Multipart PUT not supported. Use POST with _method=PUT']]);
exit;
}
parse_str(file_get_contents("php://input"), $_PUT);
// ... 同上处理
break;
关键注意事项总结
- ? $.ajax({ type: 'put' }) 应写作 'PUT'(大写),否则 jQuery 可能降级为 POST;
- ? contentType: false + processData: false 仅适用于 multipart/form-data,但 PUT 下 PHP 不支持自动解析;
- ? php://input 仅对 application/x-www-form-urlencoded 和 application/json 有效,对 multipart 为空;
- ? 生产环境建议统一 REST 接口规范:PUT 请求应使用 x-www-form-urlencoded 或 application/json,避免 multipart;
- ? 始终校验 $_PUT 中的键是否存在(使用空合并运算符 ??),防止 Undefined array key 错误;
- ? 返回响应务必使用 json_encode() 并设置 Content-Type: application/json(PHP 默认已满足)。
遵循以上方案,即可稳定获取 jQuery AJAX PUT 请求中的表单数据,彻底解决 $_PUT['id'] 报错问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











