<?php
$databasehost = "localhost";
$databasename = "test";
$databasetable = "sample";
$databaseusername ="test";
$databasepassword = "";
$fieldseparator = ",";
$lineseparator = "\n";
$csvfile = "filename.csv";
/********************************/
/* Would you like to add an ampty field at the beginning of these records?
/* This is useful if you have a table with the first field being an auto_increment integer
/* and the csv file does not have such as empty field before the records.
/* Set 1 for yes and 0 for no. ATTENTION: don't set to 1 if you are not sure.
/* This can dump data in the wrong fields if this extra field does not exist in the table
/********************************/
$addauto = 0;
/********************************/
/* Would you like to save the mysql queries in a file? If yes set $save to 1.
/* Permission on the file should be set to 777. Either upload a sample file through ftp and
/* change the permissions, or execute at the prompt: touch output.sql && chmod 777 output.sql
/********************************/
$save = 1;
$outputfile = "output.sql";
/********************************/
if (!file_exists($csvfile)) {
echo "File not found. Make sure you specified the correct path.\n";
exit;
}
$file = fopen($csvfile,"r");
if (!$file) {
echo "Error opening data file.\n";
exit;
}
$size = filesize($csvfile);
if (!$size) {
echo "File is empty.\n";
exit;
}
$csvcontent = fread($file,$size);
fclose($file);
$con = @mysql_connect($databasehost,$databaseusername,$databasepassword) or die(mysql_error());
@mysql_select_db($databasename) or die(mysql_error());
$lines = 0;
$queries = "";
$linearray = array();
foreach(split($lineseparator,$csvcontent) as $line) {
$lines++;
$line = trim($line," \t");
$line = str_replace("\r","",$line);
/************************************
This line escapes the special character. remove it if entries are already escaped in the csv file
************************************/
$line = str_replace("'","\'",$line);
/*************************************/
$linearray = explode($fieldseparator,$line);
$linemysql = implode("','",$linearray);
if($addauto)
$query = "insert into $databasetable values('','$linemysql');";
else
$query = "insert into $databasetable values('$linemysql');";
$queries .= $query . "\n";
@mysql_query($query);
}
@mysql_close($con);
if ($save) {
if (!is_writable($outputfile)) {
echo "File is not writable, check permissions.\n";
}
else {
$file2 = fopen($outputfile,"w");
if(!$file2) {
echo "Error writing to the output file.\n";
}
else {
fwrite($file2,$queries);
fclose($file2);
}
}
}
echo "Found a total of $lines records in this csv file.\n";
?>
我唯一建议的更改是使用 PDO 而不是 MySQL 函数。
阅读本文时首先想到的事情。
如今,使用 mysql_connect 几乎是不允许的……有很多可靠的面向对象解决方案。特别是像这样的网站应该为其用户提供这些代码片段的良好示例 :)
函数 split() 已弃用 – 请用 explode() 替换它
为什么不将 file() 与 str_getcsv() 结合使用?我认为它比 fopen() 更简单。您怎么看?
根据您获取 CSV 的位置,CSV 具有一个奇怪的语法,其中某些字段可能没有用双引号括起来,而某些字段可能用双引号括起来(取决于您的字段是否包含空格、另一个分隔符(逗号)等),并且它通过在双引号前添加另一个双引号来转义双引号内的双引号,等等。是的,CSV *可以*变得复杂,我认为此代码片段没有处理所有这些。
总而言之,我同意 skytrip 的普遍共识:PHP 中有很多
getcsv()
类型的函数,它们为您处理所有这些函数内容,以及它可能或可能不是那种方式的可能性。在您导出 CSV 时,还强烈建议您使用
putcsv()
风格,而不是尝试自己完成所有操作。有一个
fgetcsv
函数,它接受文件句柄、分隔符并输出一个二维数组,处理了所有棘手的 CSV 语法陷阱。此外,一个更好的解决方案可能是只使用类似 Adminer 的东西(服务器上一个文件用于处理数据库)并使用上传 CSV 文件。如果文件太大而无法上传,您可以将其放在服务器上,靠近 Adminer 文件,它可以从那里导入。
我为一家每天使用来自 50 多个提供商的 CSV 提要的公司工作。您为什么使用此解决方案而不是 LOAD DATA INFILE?
对于 CSV 中的 200k 条记录,此代码段将执行 200k 个查询。而 LOAD DATA INFILE 将使用一个。
不想成为喷子,但此代码片段存在很多问题/假设。上面列出了一些。不过,对于快速简便的解决方案,它应该可以工作。
感谢分享。
我同意这在紧急情况下可以使用。对于可能正在寻找更完善的解决方案但不想使用众多已死的 CSV 库的任何人,我在今年创建了自己的库并开源了它。它称为 Coseva,您可以在 Github 上找到它。
希望有人觉得它有用。 :)
此代码给了我类似“文件不可写,请检查权限。在此 csv 文件中找到总共 8 条记录……”的错误……任何解决方案..
精彩的教程。花了一整天的时间寻找能够将 CSV 文件插入 MySQL 数据库和 PHP 的功能……然后 BAM!它出现在我最喜欢的 CSS 网站上。干得好!(以及其他人的一些好建议)总的来说,这是一个非常棒的代码片段。谢谢!
如果我上传 csv,它只会上传 10 个中的 3 个