PHP - 上传 CSV 时遍历多个 lines/rows
PHP - Iterate through multiple lines/rows when uploading CSV
我有一个当前上传页面,我正在上传 CSV 文件并将它们导入到数据库中。它在导入然后拆分到其他表方面效果很好,但一个问题是它只导入 CSV 中的第一行。当前测试文件有 6 行,应该在一次上传时全部导入。我觉得这会使用计数器 (++) 或带有换行符 (/n) 的东西。这是我的 SQL 语句之前的上传主循环:
for($tableno = 0;$tableno < sizeof($tablenames);$tableno++){
$q = "";
$q2 = "";
$q3 = "";
$q4 = "";
$q5 = "";
$q6 = "";
$col_list = '`'.str_replace(',','`,`',$table_cols[$tableno]).'`';
$q .= "INSERT INTO ".$tablenames[$tableno]." (".$col_list.") VALUES (";
$last_id = mysqli_insert_id($connect);
$cols = explode(",",$table_cols[$tableno]);
$data = array();
foreach($cols as $key => $fldname) {
$data[] = "'".$coldata[$fldname]."'";
}
更新
这是 CSV 读取的代码:
if(isset($_POST['submit']))
{
$file = $_FILES["file"]["tmp_name"];
$handle = fopen($file, "r");
$filesop = fgetcsv($handle, 0, ",");
$coldata = array();
$coldata[ "orderNumber" ] = $filesop[0];
$coldata[ "place" ] = $filesop[1];
我对调用需要在每行的最后一列之后换行的地方有点迷糊。
您正在从文件指针读取一行 - 您需要遍历这些行直到到达 EOF。 docs 明确指出:
fgetcsv() returns NULL if an invalid handle is supplied or FALSE on other errors, including end of file.
所以你需要做类似while($returnResult !== false){.....}
的事情
PHP documentation for fgetcsv 上的第一个示例显示了如何遍历文件中的行以及行中的字段。
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
// This loops through the lines
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$row++;
// This loops through the fields
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
更新:
使用您发布的代码中的一些片段,这会从您的输入文件构建一个 multi-insert statement。它假定 $col_list
中的字段和您的 csv 文件中的相应字段顺序相同。
$q .= "INSERT INTO {$tablenames[$tableno]} ({$col_list}) VALUES "
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$rows[] = " ( '" . implode( $data, "','" ) . "' )";
}
fclose($handle);
}
$q .= implode( $rows, "," );
未经测试,但最后 $q
应该类似于
INSERT INTO example
(example_id, name, value, other_value)
VALUES
(100, 'Name 1', 'Value 1', 'Other 1'),
(101, 'Name 2', 'Value 2', 'Other 2'),
(102, 'Name 3', 'Value 3', 'Other 3'),
(103, 'Name 4', 'Value 4', 'Other 4');
当然,您正在将 CSV 文件读入各个字段,然后基本上将它们连接回一个 CSV 列表以插入。如果它们在源文件中被正确转义,则可能更容易在插入的括号内使用 fgets。
注意在插入数据库之前,您需要进行一些数据清理和转义。
我有一个当前上传页面,我正在上传 CSV 文件并将它们导入到数据库中。它在导入然后拆分到其他表方面效果很好,但一个问题是它只导入 CSV 中的第一行。当前测试文件有 6 行,应该在一次上传时全部导入。我觉得这会使用计数器 (++) 或带有换行符 (/n) 的东西。这是我的 SQL 语句之前的上传主循环:
for($tableno = 0;$tableno < sizeof($tablenames);$tableno++){
$q = "";
$q2 = "";
$q3 = "";
$q4 = "";
$q5 = "";
$q6 = "";
$col_list = '`'.str_replace(',','`,`',$table_cols[$tableno]).'`';
$q .= "INSERT INTO ".$tablenames[$tableno]." (".$col_list.") VALUES (";
$last_id = mysqli_insert_id($connect);
$cols = explode(",",$table_cols[$tableno]);
$data = array();
foreach($cols as $key => $fldname) {
$data[] = "'".$coldata[$fldname]."'";
}
更新 这是 CSV 读取的代码:
if(isset($_POST['submit']))
{
$file = $_FILES["file"]["tmp_name"];
$handle = fopen($file, "r");
$filesop = fgetcsv($handle, 0, ",");
$coldata = array();
$coldata[ "orderNumber" ] = $filesop[0];
$coldata[ "place" ] = $filesop[1];
我对调用需要在每行的最后一列之后换行的地方有点迷糊。
您正在从文件指针读取一行 - 您需要遍历这些行直到到达 EOF。 docs 明确指出:
fgetcsv() returns NULL if an invalid handle is supplied or FALSE on other errors, including end of file.
所以你需要做类似while($returnResult !== false){.....}
PHP documentation for fgetcsv 上的第一个示例显示了如何遍历文件中的行以及行中的字段。
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
// This loops through the lines
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$row++;
// This loops through the fields
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
更新:
使用您发布的代码中的一些片段,这会从您的输入文件构建一个 multi-insert statement。它假定 $col_list
中的字段和您的 csv 文件中的相应字段顺序相同。
$q .= "INSERT INTO {$tablenames[$tableno]} ({$col_list}) VALUES "
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$rows[] = " ( '" . implode( $data, "','" ) . "' )";
}
fclose($handle);
}
$q .= implode( $rows, "," );
未经测试,但最后 $q
应该类似于
INSERT INTO example (example_id, name, value, other_value) VALUES (100, 'Name 1', 'Value 1', 'Other 1'), (101, 'Name 2', 'Value 2', 'Other 2'), (102, 'Name 3', 'Value 3', 'Other 3'), (103, 'Name 4', 'Value 4', 'Other 4');
当然,您正在将 CSV 文件读入各个字段,然后基本上将它们连接回一个 CSV 列表以插入。如果它们在源文件中被正确转义,则可能更容易在插入的括号内使用 fgets。
注意在插入数据库之前,您需要进行一些数据清理和转义。