
本文详解如何使用php和mysql实现视频与图片双文件同步上传,包含html表单构建、php服务端校验与保存逻辑、数据库设计及防重复提交策略,帮助初学者避免常见错误(如文件名混淆、路径缺失、sql注入等)。
本文详解如何使用php和mysql实现视频与图片双文件同步上传,包含html表单构建、php服务端校验与保存逻辑、数据库设计及防重复提交策略,帮助初学者避免常见错误(如文件名混淆、路径缺失、sql注入等)。
在Web开发中,同时上传多种类型文件(如视频+图片)是常见需求,但初学者常因忽略文件临时路径、未校验上传状态或混淆$_FILES键名而失败。下面提供一套健壮、安全、可扩展的完整实现方案。
✅ 正确的HTML表单结构
确保的name属性与PHP中$_FILES索引严格一致,并启用enctype="multipart/form-data":
⚠️ 注意:accept属性提升用户体验;required防止空提交;name值(videofile/picturefile)必须与后端代码完全匹配。
✅ PHP服务端处理逻辑(upload.php)
以下代码完成:① 文件合法性校验(类型、大小、错误码);② 安全重命名避免覆盖与注入;③ 分别移动两个文件;④ 防重复插入(基于文件哈希去重);⑤ 使用预处理语句防止SQL注入。
<?php include "connect.php";
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit'])) {
$uploadDir = 'uploads/';
// 创建上传目录(若不存在)
if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);
// 获取两个文件信息
$video = $_FILES['videofile'] ?? null;
$picture = $_FILES['picturefile'] ?? null;
// 基础校验
if (!$video || !$picture || $video['error'] !== UPLOAD_ERR_OK || $picture['error'] !== UPLOAD_ERR_OK) {
die("错误:文件上传失败,请检查文件大小或格式。");
}
// 类型与大小限制(示例:视频≤100MB,图片≤5MB)
$maxVideoSize = 100 * 1024 * 1024;
$maxPictureSize = 5 * 1024 * 1024;
if ($video['size'] > $maxVideoSize || $picture['size'] > $maxPictureSize) {
die("错误:文件超出大小限制。");
}
// 安全重命名:用时间戳+随机数+原始扩展名
$videoExt = pathinfo($video['name'], PATHINFO_EXTENSION);
$pictureExt = pathinfo($picture['name'], PATHINFO_EXTENSION);
$videoName = uniqid('vid_') . '.' . strtolower($videoExt);
$pictureName = uniqid('pic_') . '.' . strtolower($pictureExt);
$videoPath = $uploadDir . $videoName;
$picturePath = $uploadDir . $pictureName;
// 移动文件(关键!必须使用 tmp_name)
if (!move_uploaded_file($video['tmp_name'], $videoPath) ||
!move_uploaded_file($picture['tmp_name'], $picturePath)) {
die("错误:文件保存失败,请检查目录写权限。");
}
// 可选:计算文件哈希,防止重复上传相同内容
$videoHash = md5_file($videoPath);
$pictureHash = md5_file($picturePath);
$stmt = $mysqli->prepare("SELECT id FROM usertable WHERE video_hash = ? OR picture_hash = ?");
$stmt->bind_param("ss", $videoHash, $pictureHash);
$stmt->execute();
if ($stmt->get_result()->num_rows > 0) {
unlink($videoPath); // 清理已上传文件
unlink($picturePath);
die("警告:检测到重复文件,已拒绝上传。");
}
// 安全插入数据库(预处理)
$stmt = $mysqli->prepare("INSERT INTO usertable (videofile, picturefile, video_hash, picture_hash) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $videoName, $pictureName, $videoHash, $pictureHash);
if ($stmt->execute()) {
echo "✅ 上传成功!视频:{$videoName},图片:{$pictureName}";
} else {
echo "❌ 数据库存储失败:" . $mysqli->error;
}
}
?>
✅ MySQL表结构优化建议
避免仅存文件名,应增加哈希字段用于去重,并规范字段命名与约束:
CREATE TABLE usertable ( id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, videofile VARCHAR(255) NOT NULL, picturefile VARCHAR(255) NOT NULL, video_hash CHAR(32) DEFAULT NULL, -- MD5哈希,支持唯一索引 picture_hash CHAR(32) DEFAULT NULL, upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY `unique_video_hash` (`video_hash`), UNIQUE KEY `unique_picture_hash` (`picture_hash`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
✅ 补充:安全下载文件(示例:下载视频)
为保护文件不被直接访问,建议将uploads/目录移至Web根目录外,通过脚本控制下载:
// download.php?file=vid_xxx.mp4
if (isset($_GET['file'])) {
$filename = basename($_GET['file']);
$filepath = 'uploads/' . $filename;
if (file_exists($filepath) && is_readable($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
readfile($filepath);
exit;
}
}
die('文件不存在或无权限下载。');
? 关键总结
- ✅ move_uploaded_file() 必须传入 $_FILES['xxx']['tmp_name'],而非 'name';
- ✅ 永远校验 $_FILES['xxx']['error'] 确保上传成功;
- ✅ 使用 uniqid() + 扩展名重命名,杜绝路径遍历与覆盖风险;
- ✅ 用 md5_file() 计算哈希实现内容级去重,比文件名更可靠;
- ✅ 数据库操作务必使用预处理语句,杜绝SQL注入;
- ✅ 生产环境需配置 upload_max_filesize 和 post_max_size(php.ini)。
掌握以上方法,你不仅能稳定上传双文件,更能构建出安全、可维护的文件管理基础架构。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











