PHP API图片文件验证报错及打包压缩异常问题求助
问题修复方案
一、内容类型验证错误修复
你当前的验证逻辑存在三个核心错误:
- 不应该校验
$_SERVER['CONTENT_TYPE']:文件上传请求的Content-Type固定为multipart/form-data,和上传的图片类型无关,这个判断会直接把所有合法请求拦截 - 传入
validateRequest的参数是文件名,你没有用到这个参数做校验,反而硬编码全局请求头,逻辑完全错位 - 末尾的
json_decode($request, true)完全多余,你传入的是图片文件名不是JSON格式字符串,这行代码会抛出额外报错
修改后的validateRequest方法代码:
public function validateRequest($fileName) { // 校验上传文件是否存在错误 if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) { $this->throwError(UPLOAD_FAILED, '文件上传失败'); } // 读取文件真实MIME类型,避免伪造后缀 $fileInfo = new finfo(FILEINFO_MIME_TYPE); $realMimeType = $fileInfo->file($_FILES['image']['tmp_name']); $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif']; if (!in_array($realMimeType, $allowedMimeTypes)) { $this->throwError(REQUEST_CONTENT_TYPE_NOT_VALID, '仅支持上传JPG、PNG、GIF格式的图片'); } }
二、ZIP打包及下载返回实现
你需要用到PHP内置的ZipArchive类完成打包,同时生成可公开访问的zip文件路径返回给客户端,修改逻辑如下:
1. 补充constants.php常量定义
先定义临时文件存储路径、公开访问域名等常量:
// 本地存储路径,需要确保目录有写入权限 define('RESIZED_IMAGE_DIR', __DIR__ . '/resized/'); define('ZIP_OUTPUT_DIR', __DIR__ . '/zip/'); // 公开访问前缀,对应你站点的实际访问地址 define('PUBLIC_ZIP_URL', 'https://你的站点实际域名/zip/'); // 提前创建对应目录并赋755权限 if (!is_dir(RESIZED_IMAGE_DIR)) mkdir(RESIZED_IMAGE_DIR, 0755, true); if (!is_dir(ZIP_OUTPUT_DIR)) mkdir(ZIP_OUTPUT_DIR, 0755, true);
2. 修改executeApi方法完成打包逻辑
public function executeApi() { $source = $this->request['image']; $resize = new Resizer(); // 假设imageResizer方法返回三个尺寸图片的本地路径数组 $resizedImages = $resize->imageResizer($source); // 生成唯一zip文件名 $zipFileName = uniqid('resized_images_') . '.zip'; $zipFilePath = ZIP_OUTPUT_DIR . $zipFileName; // 初始化ZipArchive $zip = new ZipArchive(); if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) { $this->throwError(ZIP_CREATE_FAILED, '压缩包生成失败'); } // 将三个尺寸的图片加入压缩包 foreach ($resizedImages as $imagePath) { $zip->addFile($imagePath, basename($imagePath)); } $zip->close(); // 删除临时生成的单张尺寸图片(可选) foreach ($resizedImages as $imagePath) { unlink($imagePath); } // 存储下载链接供response方法调用 $this->responseData = [ 'status' => true, 'download_url' => PUBLIC_ZIP_URL . $zipFileName, 'expire_time' => time() + 86400 // 可设置压缩包过期时间,定期清理旧文件 ]; }
3. 实现Rest类的response方法
public function response() { header("Content-Type: application/json"); if (!empty($this->errors)) { echo json_encode([ 'status' => false, 'errors' => $this->errors ]); } else { echo json_encode($this->responseData); } exit(); }
额外注意事项
- 所有用到的存储目录需要提前设置写入权限,避免权限不足报错
- 可添加定时任务定期清理生成的zip包,避免占用服务器存储空间
- 如果不需要保留压缩包,也可以直接输出zip文件流供用户直接下载,不需要返回下载链接
内容的提问来源于stack exchange,提问作者Mohammad Javad Farmani
相关产品推荐
相关产品推荐

