
PHP 图像上传时出现文件大小为 0,通常是因误将文件名($_FILES['image']['name'])当作 Base64 数据解码所致;实际应使用 $_FILES['image']['tmp_name'] 读取临时文件,或在客户端明确传递 Base64 内容时正确解析其值。
php 图像上传时出现文件大小为 0,通常是因误将文件名(`$_files['image']['name']`)当作 base64 数据解码所致;实际应使用 `$_files['image']['tmp_name']` 读取临时文件,或在客户端明确传递 base64 内容时正确解析其值。
在您提供的代码中,核心错误在于:混淆了文件元数据与文件内容。$_FILES['image']['name'] 仅是上传文件的原始名称(如 cat.jpg),它不是 Base64 编码的数据,对其调用 base64_decode($filename) 不仅无效,还会返回 false 或空字符串,导致 file_put_contents() 写入 0 字节文件。
此外,代码存在多个严重安全隐患和逻辑缺陷:
✅ 正确做法(推荐:标准 multipart/form-data 上传)
Postman 和 Android(如使用 OkHttp 或 Retrofit)均原生支持 multipart/form-data,无需手动 Base64 编码。应直接利用 $_FILES 的临时文件路径:
$con = mysqli_connect($host_name, $user_name, $user_pass, $db_name);
// 验证上传是否成功
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
http_response_code(400);
echo json_encode(['response' => 'Invalid image upload']);
exit;
}
$filename = $_FILES['image']['name'];
$tmp_path = $_FILES['image']['tmp_name'];
$productname = filter_input(INPUT_POST, 'productname', FILTER_SANITIZE_STRING);
$storename = filter_input(INPUT_POST, 'storename', FILTER_SANITIZE_STRING);
// 安全文件名处理(防止路径遍历/注入)
$extension = pathinfo($filename, PATHINFO_EXTENSION);
$safe_extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$allowed_types = ['jpg', 'jpeg', 'png', 'gif'];
if (!in_array($safe_extension, $allowed_types)) {
http_response_code(400);
echo json_encode(['response' => 'Unsupported file type']);
exit;
}
$upload_path = "ecomerceimage/" . uniqid() . "." . $safe_extension;
// 移动临时文件(非 base64 解码!)
if (move_uploaded_file($tmp_path, $upload_path)) {
// 插入数据库:存储相对路径或文件名(避免存敏感路径)
$stmt = $con->prepare("INSERT INTO `imageinfo` (`image`, `storename`, `productname`) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $filename, $storename, $productname);
if ($stmt->execute()) {
echo json_encode(['response' => 'Image uploaded successfully']);
} else {
echo json_encode(['response' => 'Database insertion failed']);
}
$stmt->close();
} else {
http_response_code(500);
echo json_encode(['response' => 'Failed to save file']);
}
mysqli_close($con);
⚠️ 若坚持使用 Base64(不推荐,但 Android 某些场景可能采用)
则客户端必须发送形如 {"image_base64": "data:image/png;base64,..."} 的 JSON,并在 PHP 中解析:
$data = json_decode(file_get_contents('php://input'), true);
if (isset($data['image_base64'])) {
$base64_str = $data['image_base64'];
// 提取 Base64 数据部分(去掉 data:...;base64, 前缀)
$base64_str = preg_replace('#^data:image/\w+;base64,#i', '', $base64_str);
$binary_data = base64_decode($base64_str);
if ($binary_data === false) {
http_response_code(400);
echo json_encode(['response' => 'Invalid base64 string']);
exit;
}
file_put_contents($upload_path, $binary_data); // 此时才可 base64_decode
}
? 关键注意事项总结:
- ❌ 绝对不要对
$_FILES['x']['name']调用base64_decode();它只是字符串,不是编码数据。 - ✅ 使用
move_uploaded_file()处理标准表单上传,安全高效。 - ? 始终验证
$_FILES['x']['error']、文件类型、大小($_FILES['x']['size'])及扩展名。 - ?️ 使用预处理语句(
mysqli_prepare)防止 SQL 注入,禁用直接拼接$_POST值。 - ? 存储路径建议使用唯一文件名(如
uniqid()+ 扩展名),避免同名覆盖或命名冲突。 - ? Android 端请优先使用
MultipartBody构造请求,而非手动 Base64 编码图像(后者显著增加体积和内存开销)。
遵循上述实践,即可彻底解决“上传图像大小为 0”的问题,并构建健壮、安全的图像上传服务。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











