如何通过HTML表单上传的CSV文件,使用mysqli_query进行导入?
我读了这个问答 PHP MySQL LOAD DATA INFILE from CSV File Upload 以及其他关于如何使用mysqli_query和 LOAD DATA LOCAL INFILE的文章。
但我找不到任何关于 HTML表单实际是如何用于上传文件、以及上传到mysqli_query可以导入的位置 的细节。我的问题与其他人不同,因为我找不到关于如何使用HTML表单上传CSV文件的有效示例。
下面的代码根本无法导入文件。没有PHP错误。我使用的是PHP 8+、MySQL 8。MySQLi连接 $connect 测试通过。
我想把所有代码都放在同一页上(我不需要Ajax),上传后页面重载也无所谓。
• 如何把上传的文件作为 $_FILES?
• 如何在上传表单的action中触发 $import_csv?
感谢任何帮助!
更新3/4/26: 感谢大家对安全性的关切;我理解你的观点。但这个上传功能仅在网站的受保护后台由一个人非常有限地使用。
<?php
if( isset($_POST['submit']) )
{
$connect = mysqli_connect("DB_HOST","DB_USER","DB_PASSWORD","DB_NAME");
$uploaded = $_FILES["fileupload"]["name"];
$import_csv = mysqli_query($connect,"LOAD DATA LOCAL INFILE $uploaded INTO TABLE table_name FIELDS TERMINATED BY ',' IGNORE 1 LINES; ");
}
; ?>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="fileupload" accept=".csv" required>
<input type="submit" value="Upload">
</form>
解决方案
但我找不到关于HTML表单实际如何上传文件,以及上传到mysqli_query可以导入的位置的细节。
你首先需要知道mysqli_query能从哪里导入它。就在那个位置创建一个测试CSV文件并验证mysqli_query是否能够导入它。
这是一个重要步骤,以确保 "MySQL有权读取文件所在的目录。",正如 [Rick James] 的评论所示。
接下来验证你是如何 [处理文件上传] 的:
$uploaded = $_FILES["fileupload"]["name"];
[POST method uploads] 解释了:
$_FILES['userfile']['name']
客户端机器上的文件原始名称。
警告:切勿使用用户提供的 'name',那是一个巨大的安全风险。 (下方有更多信息)
除了危险性之外,那个 'name' 仅供参考(客户端机器 = 提交表单的用户的计算机,即上传者),你需要在同一系统上一个实际的路径名来加载infile:
$_FILES['userfile']['tmp_name']
上传的文件在服务器上的临时文件名。
上传的文件是临时的,参阅 [is_uploaded_file()] 的 [示例#1 is_uploaded_file() 示例]。
php if (is_uploaded_file($_FILES['userfile']['tmp_name'])) { echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n"; echo "Displaying contents\n"; readfile($_FILES['userfile']['tmp_name']); } else { echo "Possible file upload attack: "; echo "filename '". $_FILES['userfile']['tmp_name'] . "'."; }
这个示例清单同时展示了 'name' 和 'tmp_name' 的用法。
替代 [readfile()],你应让MySQL通过 'LOAD DATA LOCAL INFILE' 查询来读取它。
如果你需要先移动上传的文件,请参阅 [move_uploaded_file()],并在PHP手册的 [Handling File Uploads] 一节中了解更多。
警告:切勿使用用户提供的 'name',这是一种安全风险。
举例来说,在你的代码中:
sql mysqli_query($connect,"LOAD DATA LOCAL INFILE $uploaded INTO TABLE table_name FIELDS TERMINATED BY ',' IGNORE 1 LINES; ");
变量 $uploaded包含任意字符串数据,用户可以把它注入到SQL查询中,从而完全改变查询。请参阅关于SQL注入的警告,见 [mysqli_query()],了解如何防止此类注入。