PHP文件上传代码:SQL写入正常但文件无法移动报错求助
解决move_uploaded_file无法移动文件的问题
嘿,我仔细看了你的报错信息和代码,马上发现了最核心的问题,咱们一步步来解决:
1. 路径拼接的致命错误
从报错信息里的/Applications/XAMPP/xamppfiles/htdocsupload/files/...就能看出来——htdocs和upload之间少了一个斜杠!因为$_SERVER['DOCUMENT_ROOT']的值是/Applications/XAMPP/xamppfiles/htdocs(XAMPP默认的网站根目录),你直接拼接"upload/files/"的话,两个字符串就粘在一起变成htdocsupload了,系统找不到这个不存在的目录,自然报错。
修复方法
给upload前面加个斜杠就行:
$targetPath = $_SERVER['DOCUMENT_ROOT'] . "/upload/files/" . $name; move_uploaded_file($temp, $targetPath);
如果想适配Windows/Linux不同的路径分隔符,用PHP内置的DIRECTORY_SEPARATOR更稳妥:
$targetPath = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "upload" . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR . $name;
2. 其他需要排查的坑
即使路径修好了,也可能遇到其他问题,建议一起检查:
- 目标目录权限不够:确保
/Applications/XAMPP/xamppfiles/htdocs/upload/files/目录是可写的(一般设为755或775,别用777,不安全)。终端里可以用这个命令改权限:chmod -R 755 /Applications/XAMPP/xamppfiles/htdocs/upload/files/ - 文件名有特殊字符:空格、中文、奇怪符号都可能导致路径解析失败。可以给文件名做个“安全处理”:
// 把非字母数字/下划线/点的字符换成下划线 $safeName = preg_replace('/[^a-zA-Z0-9_\.]/', '_', $name); $targetPath = $_SERVER['DOCUMENT_ROOT'] . "/upload/files/" . $safeName; - 目录不存在:如果
upload/files目录还没创建,move_uploaded_file也会失败。可以自动创建目录:$targetDir = $_SERVER['DOCUMENT_ROOT'] . "/upload/files/"; if (!is_dir($targetDir)) { mkdir($targetDir, 0755, true); // true表示递归创建多级目录 } - 加个错误判断:给
move_uploaded_file加个返回值检查,方便调试:if (!move_uploaded_file($temp, $targetPath)) { echo "文件移动失败:" . error_get_last()['message']; }
3. 修复后的完整代码示例
if (isset($_POST['submit'])) { $name = $_FILES['file']['name']; $temp = $_FILES['file']['tmp_name']; // 处理文件名,避免特殊字符问题 $safeName = preg_replace('/[^a-zA-Z0-9_\.]/', '_', $name); // 拼接正确的目标路径 $targetDir = $_SERVER['DOCUMENT_ROOT'] . "/upload/files/"; $targetPath = $targetDir . $safeName; // 自动创建目录(如果不存在) if (!is_dir($targetDir)) { mkdir($targetDir, 0755, true); } // 移动文件并处理结果 if (move_uploaded_file($temp, $targetPath)) { $url = "http://localhost/upload/files/" . $safeName; // 注意:这里的SQL有注入风险,建议用预处理语句! $sql = "INSERT INTO photo (NAME,link) VALUES ('$safeName','$url')"; // 记得执行SQL,比如用mysqli或PDO: // $conn = mysqli_connect("localhost", "你的用户名", "你的密码", "你的数据库名"); // mysqli_query($conn, $sql); echo "上传成功!"; } else { echo "上传失败:" . error_get_last()['message']; } }
最后提醒一下:你的SQL语句直接把变量拼进去,存在SQL注入风险,一定要用mysqli或PDO的预处理语句来执行,别直接这样写哦!
内容的提问来源于stack exchange,提问作者aleko xvadagiani
相关产品推荐
相关产品推荐

