无法通过move_uploaded_file上传图片,请求故障排查建议
拖拽上传图片PHP报错排查
拖拽上传系统JS运行正常,但PHP端出现以下警告:
PHP Warning: move_uploaded_file(assets/img/photos/1657614494809.jpg): failed to open stream: No such file or directory in /www_root/_inc/upload.php on line 29, referer: https://smartobchod.sk/bazar/add.php [Sat Jul 23 12:56:18 2022] [error] [client 78.99.32.1] PHP Warning: move_uploaded_file(): Unable to move '/home/gm016900/tmp/phpKaBL6m' to 'assets/img/photos/1657614494809.jpg' in /www_root/_inc/upload.php on line 29, referer: https://smartobchod.sk/bazar/add.php
2022年7月25日更新(已添加安全检查)
以下是upload.php中的PHP代码:
<?php // 获取上传图片的引用 $image_file = $_FILES["file"]; // 获取图片名称 $image_name = $_FILES["file"]["name"]; // 获取文件大小 $image_size = $_FILES["file"]["size"]; // 若未上传文件或文件名包含非法字符/、\则终止 if ( ( !strpos($image_name, '/') || !strpos($image_name, '\\') ) && isset($image_file) ) { $errors = array(); $maxsize = 10485760; $acceptable = array( 'image/jpeg', 'image/jpg', 'image/gif', 'image/png' ); } else { die('No image uploaded.'); } // 若图片文件为空或大小超过10MB则终止 if (getimagesize($image_file["tmp_name"]) <= 0) { die('Uploaded file has no contents.'); } elseif ($image_size >= $maxsize) { die('Image is too large. Image must be less than 10 megabytes.'); } // 若不是有效图片文件或格式不支持则终止 $image_type = exif_imagetype($image_file["tmp_name"]); if (!$image_type) { die('Uploaded file is not an image.'); } elseif ( !in_array($image_file["type"], $acceptable) ) { die('Image has not supported type JPG, PNG, GIF.'); } else { $src = "default.png"; } // 根据文件类型获取扩展名,第二个参数传true自动添加前缀点 $image_extension = image_type_to_extension($image_type, true); // 创建唯一图片名称 $image_name = bin2hex(random_bytes(16)) . $image_extension; // 文件存储路径 $relative_location = "/bazar/assets/img/photos/" . $image_name; $absolute_location = dirname(__DIR__, 2) . $relative_location; $return_arr = array(); // 将临时文件移动到图片存储目录 if (move_uploaded_file($image_file["tmp_name"], $absolute_location)) { $src = $relative_location; $return_arr = array("name" => $image_name,"size" => $image_size, "src"=> $src); } echo json_encode($return_arr);
发送至upload.php的请求头如下:
Content-Disposition: form-data; name="file"; filename="1657614494809.jpg" Content-Type: image/jpeg
问题原因及解决方案
核心问题:目标目录不存在或权限不足
错误提示明确指出failed to open stream: No such file or directory,说明move_uploaded_file尝试写入的目录不存在,或者Web服务器进程没有该目录的写入权限。
具体排查与修复步骤:
验证目标路径正确性
在move_uploaded_file前添加代码打印绝对路径,确认路径是否符合预期:echo $absolute_location; exit;比如
dirname(__DIR__, 2)返回/www_root的话,完整路径应为/www_root/bazar/assets/img/photos/[文件名],需要确认该路径对应的物理目录真实存在。自动创建缺失的目录
如果目录不存在,在移动文件前递归创建目录并设置合理权限:$target_dir = dirname($absolute_location); if (!is_dir($target_dir)) { // 0755表示所有者可读可写可执行,其他用户可读可执行 mkdir($target_dir, 0755, true); }修复目录权限
确保Web服务器进程(如www-data、apache)对目标目录有写入权限,可通过命令行设置:chown -R www-data:www-data /www_root/bazar/assets/img/photos/ chmod -R 755 /www_root/bazar/assets/img/photos/修正代码逻辑bug
- 原安全检查逻辑错误:
( !strpos($image_name, '/') || !strpos($image_name, '\\') )应改为( !strpos($image_name, '/') && !strpos($image_name, '\\') ),只要文件名包含/或\就应该拒绝上传。 getimagesize的判断逻辑不合理,该函数失败返回false,成功返回数组,应改为:if (!getimagesize($image_file["tmp_name"])) { die('Uploaded file has no contents or is not a valid image.'); }
- 原安全检查逻辑错误:
内容的提问来源于stack exchange,提问作者Dump
相关产品推荐
相关产品推荐

