
json 请求体无法直接携带二进制文件,需将文件转为 base64 编码字符串嵌入对象字段;后端 php 需主动解码还原,而非依赖 $_files(该变量仅适用于 multipart/form-data 请求)。
在构建 REST API 时,一个常见误区是试图在 application/json 类型的 raw 请求体中直接“放入”文件(如通过 "upload_file":
例如,你的请求体应改为如下格式:
{
"id": 1,
"mydata": [
{
"entity_id": 1,
"upload_file": "UEsDBBQAAAAIAJiR..." // Base64 编码后的文件内容(如 PNG、PDF 等)
},
{
"entity_id": 2,
"upload_file": "iVBORw0KGgoAAAANSUhEUg..."
}
]
}⚠️ 注意:
- Base64 编码会使数据体积膨胀约 33%,不适合大文件(建议单文件 ≤ 5 MB);
- 必须在 JSON 中明确约定字段语义(如 upload_file 表示 Base64 编码的原始文件内容,非文件名或路径);
- 前端需确保正确读取文件并编码(如 JavaScript 使用 FileReader.readAsDataURL() 后截取 base64 部分),后端需严格校验和解码。
PHP 后端接收与处理示例:
立即学习“PHP免费学习笔记(深入)”;
// 1. 获取原始 JSON 输入
$jsonInput = file_get_contents('php://input');
$data = json_decode($jsonInput, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
// 2. 遍历 mydata 数组,解码并保存每个 upload_file
foreach ($data['mydata'] as $item) {
$entityId = $item['entity_id'] ?? null;
$base64Data = $item['upload_file'] ?? '';
if (empty($base64Data)) {
continue; // 跳过空文件
}
// 验证 Base64 格式(简化版)
if (!preg_match('/^data:(.*?);base64,(.*)$/i', $base64Data, $matches)) {
// 若无 data URL 前缀,直接尝试解码(假设纯 base64 字符串)
$binary = base64_decode($base64Data);
} else {
$binary = base64_decode($matches[2]);
}
if ($binary === false) {
throw new InvalidArgumentException("Invalid Base64 string for entity_id: $entityId");
}
// 3. 可选:推断 MIME 类型(如需)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_buffer($finfo, $binary);
finfo_close($finfo);
// 4. 保存文件(示例:按 entity_id 命名)
$filename = "/uploads/entity_{$entityId}_" . date('YmdHis') . '.bin';
file_put_contents($filename, $binary);
// ✅ 此时 $binary 即为原始文件字节流,可进一步校验、转存、解析等
}? 关键总结:
- $_FILES 全局变量仅在 multipart/form-data 请求中自动填充,对 JSON 请求完全不可用;
- 若需保留 $_FILES 的便利性(如自动临时文件、大小限制、错误码等),应改用 form-data 模式,并将 mydata 数组序列化为字段名(如 mydata[0][entity_id] + mydata[0][upload_file]),但需服务端做特殊解析;
- Base64 方案简洁、跨平台兼容性强,是 JSON-first 架构下的标准实践,但务必配套实现完整性校验(如添加 upload_file_hash 或 upload_file_size 字段辅助验证)。
选择方案前,请根据实际场景权衡:小文件、强结构化需求 → 用 Base64 + JSON;大文件、上传进度/断点续传需求 → 回归 multipart/form-data + 自定义字段解析。











