You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP旅游信息(Name、Image)上传异常:文件未保存至upload目录

解决PHP文件上传仅存文件名、文件未上传至目录的问题

咱们来一步步排查并解决你遇到的问题,核心原因集中在表单配置、文件上传逻辑以及数据传递方式上:

核心问题拆解

  • 表单缺失关键属性:文件上传的表单必须添加enctype="multipart/form-data",否则服务器无法接收上传的文件,$_FILES数组会是空的。
  • 文件上传逻辑错误:你试图从$_POST['tour_img']获取文件信息,但文件上传的真实数据存于$_FILES超全局数组;同时move_uploaded_file的路径处理不完整,也没有做上传成功的校验。
  • SESSION传递数据不合理:依赖SESSION存文件名和路径不仅冗余,还容易导致逻辑混乱,直接在提交时把正确的文件路径传给业务方法更可靠。

修正后的完整代码示例

1. 调整Add_tour.php的表单与上传逻辑

<?php 
session_start(); // 若项目未全局开启SESSION,需手动开启
$app = new app(); 
$targetDir = __DIR__ . "/upload/"; // 使用绝对路径避免服务器路径解析问题

// 确保上传目录存在,不存在则自动创建
if (!is_dir($targetDir)) {
    mkdir($targetDir, 0755, true);
}

$tour_name = '';
$tour_img_path = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 处理旅游名称字段
    $tour_name = isset($_POST['tour_name']) ? trim($_POST['tour_name']) : '';
    
    // 处理文件上传逻辑
    if (isset($_FILES['tour_img']) && $_FILES['tour_img']['error'] === UPLOAD_ERR_OK) {
        $originalFileName = basename($_FILES['tour_img']['name']);
        // 给文件名加时间戳前缀,避免重名覆盖
        $uniqueFileName = time() . '_' . $originalFileName;
        $targetFile = $targetDir . $uniqueFileName;
        
        // 移动临时文件到目标目录
        if (move_uploaded_file($_FILES['tour_img']['tmp_name'], $targetFile)) {
            // 存储相对路径到数据库,方便前端调用
            $tour_img_path = '/upload/' . $uniqueFileName;
        } else {
            echo "文件上传失败,请检查upload目录的写入权限";
        }
    }
    
    // 验证参数有效后,调用添加方法
    if (!empty($tour_name) && !empty($tour_img_path)) {
        $ID = $app->add_tour($tour_name, $tour_img_path);
        // 可在此添加成功提示或页面跳转逻辑
    }
}
?>

<!-- 表单添加enctype属性,补充提交按钮 -->
<form action="/admin/add_tour.php" method="post" enctype="multipart/form-data">
    <input type="text" class="form-control" id="tour_name" name="tour_name" required>
    <input type="file" data-toggle="custom-file-input" id="tour_img" name="tour_img" required>
    <button type="submit">提交旅游信息</button>
</form>

2. 优化app.class.php的add_tour方法

把依赖SESSION的逻辑改为直接接收参数,更清晰安全:

public function add_tour($tour_name, $tour_img_path){
    // 先校验参数有效性
    if (empty($tour_name) || empty($tour_img_path)) {
        return 0;
    }
    
    // 转义数据防止SQL注入
    $escaped_name = $this->db->escape($tour_name);
    $escaped_img_path = $this->db->escape($tour_img_path);
    
    // 检查是否已存在相同记录
    $res = $this->db->RawQuery("SELECT id FROM `table` WHERE tour_name = '$escaped_name' AND tour_img = '$escaped_img_path' LIMIT 1;");
    $id = 0;
    foreach($res as $row) {
        $id = $row['id'];
    }
    
    // 不存在则插入新记录
    if ($id == 0) {
        $data = "tour_name = '$escaped_name', tour_img = '$escaped_img_path'";
        $id = $this->db->RawQuery("INSERT INTO `table` SET $data;");
    }
    
    return $id;
}

额外注意事项

  • 目录权限:确保upload目录拥有服务器写入权限(一般设置为0755或0775),否则move_uploaded_file会执行失败。
  • 文件安全校验:可以添加文件类型(如仅允许jpg/png)和大小限制,防止恶意文件上传。
  • SQL注入防护:虽然你用了escape方法,但更推荐使用预处理语句,比手动转义的安全性更高。

内容的提问来源于stack exchange,提问作者Amine Khaoui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:54:14