
在web开发中,文件上传是一个常见的功能需求。然而,在将文件保存到服务器目录的同时,如何安全、准确地将其相关信息记录到数据库中,常常会遇到一些挑战。本文将针对文件上传成功但数据库记录失败这一典型问题,进行深入剖析并提供一套专业的解决方案。
原始代码中文件能够成功上传到指定目录,但数据库记录失败,主要原因在于以下两点:
SQL注入风险与数据类型不匹配: $insert = "INSERT INTO lessons (lesson_no, name, description, date, file) VALUES ($lessonNo, '$lessonName', '$description', '$date', '$fileName');"; 此SQL语句直接将PHP变量拼接到SQL字符串中。
不正确的条件判断逻辑:
$result_insert = mysqli_query($conn,$insert);
if($insert){ // 错误:这里判断的是SQL查询字符串本身
$statusMsg = "The file ".basename($_FILES['lfile']['name']). " has been uploaded successfully.";
}
else{
$statusMsg = "File upload failed, please try again.";
}在执行 mysqli_query($conn,$insert) 后,正确的做法是检查 $result_insert 变量的布尔值来判断查询是否成功。$insert 变量存储的是SQL查询字符串,它永远是一个非空的字符串,在布尔上下文中会被评估为 true。因此,if($insert) 永远为真,即使数据库操作失败,也会错误地显示成功信息。
为了解决上述问题并确保文件上传功能的安全性与健壮性,我们应遵循以下最佳实践:
立即学习“PHP免费学习笔记(深入)”;
以下是基于上述原则优化后的PHP文件上传与数据库记录代码:
<?php
// 数据库连接配置
$host = "localhost";
$dbUsername = "root";
$dbPassword = "";
$dbName = "abc_school";
// 创建数据库连接
$conn = mysqli_connect($host, $dbUsername, $dbPassword, $dbName);
// 检查连接是否成功
if (!$conn) {
die("数据库连接失败: " . mysqli_connect_error());
}
// 定义文件上传目录
$targetDir = "uploads/";
$statusMsg = ""; // 初始化状态消息
// 检查是否提交了表单且选择了文件
if (isset($_POST["upload"]) && !empty($_FILES['lfile']['name'])) {
$lessonNo = $_POST['lno'];
$lessonName = $_POST['lname'];
$description = $_POST['ldescription'];
$date = $_POST['ldate']; // 注意:日期格式可能需要进一步验证或转换
$originalFileName = basename($_FILES['lfile']['name']);
$fileType = strtolower(pathinfo($originalFileName, PATHINFO_EXTENSION));
// 生成唯一文件名,防止文件覆盖和潜在的安全问题
$newFileName = uniqid() . '_' . time() . '.' . $fileType;
$targetFilePath = $targetDir . $newFileName;
// 允许的文件类型
$allowTypes = array('jpg', 'png', 'jpeg', 'gif', 'pdf');
// 验证文件类型
if (in_array($fileType, $allowTypes)) {
// 移动文件到服务器目录
if (move_uploaded_file($_FILES['lfile']['tmp_name'], $targetFilePath)) {
// 使用预处理语句插入数据到数据库
$stmt = $conn->prepare("INSERT INTO lessons (lesson_no, name, description, date, file) VALUES (?, ?, ?, ?, ?)");
// 检查预处理语句是否成功
if ($stmt === false) {
$statusMsg = "数据库预处理语句失败: " . $conn->error;
} else {
// 绑定参数
// 'issss' 表示参数类型:i=integer, s=string
$stmt->bind_param("issss", $lessonNo, $lessonName, $description, $date, $newFileName);
// 执行预处理语句
if ($stmt->execute()) {
$statusMsg = "文件 " . htmlspecialchars($originalFileName) . " 已成功上传并记录到数据库。";
} else {
$statusMsg = "文件上传成功,但数据库记录失败: " . $stmt->error;
// 如果数据库记录失败,可能需要删除已上传的文件
if (file_exists($targetFilePath)) {
unlink($targetFilePath);
}
}
// 关闭语句
$stmt->close();
}
} else {
$statusMsg = "抱歉,上传文件时发生错误。";
}
} else {
$statusMsg = "抱歉,只允许上传 JPG, JPEG, PNG, GIF, & PDF 文件。";
}
} else {
$statusMsg = "请选择一个文件上传。";
}
// 关闭数据库连接
mysqli_close($conn);
echo $statusMsg;
?>通过遵循这些最佳实践和使用预处理语句,您可以构建一个更安全、更可靠的PHP文件上传与数据库记录系统。
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号