PHP实现多张图片上传功能:HTML表单与后端处理完整示例

青禾
青禾
发布时间:2026-10-15 | 4人浏览过
原创

在Web开发中,支持一次选择并上传多张图片是常见的需求。本文将详细介绍如何利用HTML表单配合JavaScript动态增加上传控件,使用PHP的move_uploaded_file函数批量处理上传的文件,并将图片路径保存至MySQL数据库,最终在前端实现图片的循环读取与展示。

结果与目标

实现一个完整的图片上传流程:前端允许用户通过按钮动态增加输入框以选择多个文件,后端接收这些文件进行合法性校验和移动操作,成功上传后将所有图片的相对路径整合成一个字符串存入数据库,并在页面中将这些图片正确渲染出来。

准备条件

  • 已搭建好本地或服务器端的 PHP 运行环境(如 WAMP/XAMPP)。
  • MySQL 数据库中已创建名为 image 的数据库,并建立表 img,包含至少一个字段 name 用于存储图片路径字符串。

  • 确保脚本运行的目录存在用于存放上传文件的文件夹(例如 img/)。

真实操作顺序

第1步:构建前端上传界面

目的:创建一个允许用户上传多个文件的 HTML 页面,并通过简单的 JavaScript 实现点击按钮后“继续添加图片”的输入框,从而支持一次性选择或分批追加图片提交。

前端页面的核心在于表单配置:method="post" 指定请求方式,enctype="multipart/form-data" 是发送二进制文件数据必须的属性。以下是完整的 HTML/CSS/JS 代码:

<html>
<head><title>多个文件上传表单</title></head>
<body>
<style>
    form {
        margin: 20px;
        padding: 10px;
    }
    #picInput > input {
        display: block;
        margin: 10px;
    }
</style>
<form action="pic.php" method="post" enctype="multipart/form-data">
    <!-- 设置最大文件大小限制为 1MB -->
    <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
    <div id="picInput">
        上传图片:<input type="file" name='myfile[]'>
    </div>
    <input id="addBtn" type="button" onclick="addPic1()" value="继续添加图片"><br/><br/>
    <input type="submit" value="上传文件">
</form>
 <script>
    // 点击按钮时动态生成新的 file input
    function addPic1(){
        var addBtn = document.getElementById('addBtn');
        var input = document.createElement("input");
        input.type = 'file';
        input.name = 'myfile[]'; // 保持数组名称一致以便 PHP 接收
        var picInut = document.getElementById('picInput');
        picInut.appendChild(input);
        
        // 可选:限制最多只允许再添加一定数量,防止页面过于冗长
        if(picInut.children.length == 3){
            addBtn.disabled = 'disabled';
        }
    }
</script>
</body>
</html>

第2步:编写 PHP 接收并处理图片

目的:接收前端传来的多维数组形式的文件信息,校验文件格式,将合法的临时文件移动到指定的持久化目录,并记录路径以备后续入库。

核心函数 move_uploaded_file() 负责将上传的临时文件安全地移动到新位置。在处理多张图片时,我们需要遍历 $_FILES 数组。代码如下:

<meta charset="UTF-8">
<?php
// 数据库连接配置
$dbhost = 'localhost:3306';
$dbuser = 'root';
$dbpass = 'root';
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn ){
    die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
mysqli_select_db( $conn, 'image' );

$file = $_FILES['myfile']; // 获取传输的数据,以数组形式返回
$name = $file['name'];     // 获取文件名数组
$upload_path = "img/";     // 图片存放物理路径

// 第一次遍历:过滤不合法的后缀名
foreach ($name as $key => $names){
    // 截取最后一个点之后的字符作为后缀,并转为小写
    $type = strtolower(substr($names, strrpos($names, '.')+1));
    $allow_type = array('jpg', 'jpeg', 'gif', 'png'); // 允许的图片类型
    
    if (!in_array($type, $allow_type)){
        unset($name[$key]); // 若格式不符,从待处理列表中移除该元素
        unset($file['tmp_name'][$key]); // 同时清理对应的临时文件索引,保持数组同步
        unset($file['size'][$key]);
    }
}

$str = ''; // 用于拼接数据库路径字符串
// 第二次遍历:处理剩余合法文件
foreach ($name as $key => $item){
    $type = strtolower(substr($item, strrpos($item, '.')+1));
    // move_uploaded_file 参数:源临时路径 -> 目标永久路径
    // 注意:原代码 time().$name[$key] 可能导致同名文件覆盖,实际生产建议加随机数或ID
    if (move_uploaded_file($file['tmp_name'][$key], $upload_path.time().$name[$key])){
        $str .= ',' . $upload_path.time().$name[$key]; // 累加路径
    } else {
        echo '单个图片上传失败';
    }
}

// 向数据库插入数据
// 去掉最前面的逗号
$str = substr($str, 1); 
$sql = "INSERT INTO img (name) VALUES ('$str')";
$retval = mysqli_query( $conn, $sql );
if(! $retval ){
    die('无法插入数据: ' . mysqli_error($conn));
}
echo "数据插入成功";
mysqli_close($conn);
?>

第3步:读取数据库并回显图片

目的:从 MySQL 中取出存储的路径字符串,将其分割为数组,然后循环生成 <img /> 标签显示在网页上。

由于我们在上传时将多个路径拼接成了逗号分隔的字符串,读取时需要先使用 explode 函数拆分。

<meta charset="UTF-8">
<style>
    .image {
        width: 150px;
        height: 150px;
        border: 1px solid #ccc;
    }
</style>
<?php
// 重复数据库连接代码(实际项目中建议封装成 config.php 引入)
$dbhost = 'localhost:3306';
$dbuser = 'root';
$dbpass = 'root';
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn ){
    die('连接失败: ' . mysqli_error($conn));
}
mysqli_query($conn , "set names utf8");
mysqli_select_db( $conn, 'image' );

$sql = 'SELECT name FROM img'; // 查询所有图片路径记录
$retval = mysqli_query( $conn, $sql );
if(! $retval ){
    die('无法读取数据: ' . mysqli_error($conn));
}

$picpath_raw = '';
while($row = mysqli_fetch_array($retval)){
    $picpath_raw .= $row[0] . '|'; // 使用 '|' 分隔不同记录的组,便于后续扩展
}

if($picpath_raw != '') {
    // 分割不同条记录
    $records = explode('|', rtrim($picpath_raw, '|'));
    foreach ($records as $record) {
        // 进一步分割单条记录中的图片路径
        $pic_paths = explode(',', $record);
        foreach($pic_paths as $path) {
            if(!empty($path)) {
                echo "<img class='image' src='".$path."' />";
            }
        }
    }
} else {
    echo "暂无图片";
}

mysqli_close($conn);
?>

完成判断

当你在浏览器打开 HTML 页面,点击“继续添加图片”并选择多张图片后点击“上传文件”,如果页面提示“数据插入成功”,说明后端处理完毕。刷新执行第三步代码的页面,你应该能看到刚才上传的所有缩略图按顺序排列显示。

原文有依据的排错

  • 文件重名覆盖风险:原代码中使用 $upload_path.time().$name[$key] 命名。如果两秒内上传了同名的图片,会发生覆盖。建议在时间戳后加入随机字符串或 uniqid()。
  • SQL注入防范:示例代码直接拼接了 $str 到 SQL 语句中。在生产环境中,应始终使用 mysqli_prepare 预处理语句来绑定参数,以防止恶意代码注入。
  • 数据库字段长度:如果上传几十张甚至上百张图片,拼接后的字符串可能非常长。请确保 MySQL 表中 name 字段的类型至少为 MEDIUMTEXT 或 LONGTEXT,否则会导致截断报错。

简要总结

以上就是 PHP 实现多张图片上传、入库及回显的详细内容。掌握 move_uploaded_file 的多维数组处理逻辑以及前后端数据的交互方式是关键。更多关于 PHP 多媒体处理和数据库优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表