【问题标题】:PHP - fgetcsv loop for get data from csv file column by columnPHP - fgetcsv 循环用于逐列从 csv 文件中获取数据
【发布时间】:2016-12-13 12:49:18
【问题描述】:

我有一个包含 31 列和 24 行的 CSV 文件。我需要fgetcsv(或者可能是其他解决方案)传入CSV并逐列获取数据。我有一个解决方案:

 // { ?
  for ($col=1; $col<=32; $col++) {
    while ($data = fgetcsv($read, max, ";")) {          
      $row[] = $data[$col];
    }
    print_r($row);
    //... in the line behind i have sql query to insert data in base.   
  }  
  unset($row);  
}

for 循环正在工作,但 $data[$col] 仅从 CSV 的第一列获取数据,当 $col234 时,它不会从 $data[$col] 获取数据, ...,31

我在哪里犯了错误,问题是什么?代码对我来说看起来不错,但我认为我对 fgetcsv 函数一无所知。

max 是 CSV 的文件大小,fgetcsv 就像文件的最大大小一样。无论fgetcsv 中有什么内容,他们只会看到第一列,而不是每次$col 更改时都循环。

insert = "INSERT INTO xxxx (v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24) VALUES ('$row[1]','$row[2]','$row[3]','$row[4]','$row[5]','$row[6]','$row[7]','$row[8]' '$row[9]','$row[10]','$row[11]','$row[12]','$row[13]','$row[14]','$row[15]','$row[16]','$row[17]','$row[18]','$row[19]','$row[20]','$row[21]','$row[22]','$row[23]','$row[24]')"

【问题讨论】:

  • fgetcsv($read,max,";") - max 的值是多少?
  • 数据是什么样的?
  • 请发布数据示例。您可以在while 大括号打开后使用:die('&lt;pre&gt;'.print_r($data, 1));
  • fgetcsv($read, max, ";") 这合法吗? max 是什么?
  • fgetcsv 获取一行,而不是一列。

标签: php csv fgetcsv


【解决方案1】:

在您的代码中:

for ($col=1; $col<=32; $col++) {
  while ($data = fgetcsv($read, max, ";")) {

您正尝试从文件中获取 所有 行 32 次。第一次迭代从文件中获取所有行,因为while 循环在fgetcsv 返回false 时结束(当没有更多数据要读取时)。

我需要fgetcsv(或其他解决方案)传入csv并逐列获取数据。

您不能逐列读取数据,因为文件是逐行读取的,而行代表表格行。如果要按列对表格数据进行迭代,可以将整个表格读入一个数组,然后交换行和单元格:

$table = [];
while ($row = fgetcsv($fp)) {
  $table []= $row;
}

for ($r = 0; $r < count($table); $r++) {
  for ($c = 0; $c < count($table[$r]); $c++) {
    $new_table[$c][$r] = $table[$r][$c];
  }
}

// Use $new_table to iterate the table "by columns"
foreach ($new_table as $column) {
  foreach ($column as $cell) {
    $fields []= $cell;
  }
  $fields = implode(',', $cell);
  // do_something($fields)
}

因此您不需要外部循环迭代列“索引”,因为fgetcsv 已经为包含单元格值的下一行获取了一个数组:

$row = fgetcsv($fp);
// $row = ['column 0 cell', 'column 1 cell', ... ]

至少,将循环放入获取行的while 循环。如果你想迭代单元格,迭代fgetcsv返回的值。

示例

$fp = fopen('test.csv', 'w+');

for ($i = 0; $i < 4; $i++) {
  for ($j = 0; $j < 6; $j++) {
    $a[$i][$j] = "r $i c $j";
  }
  fputcsv($fp, $a[$i]);
}

rewind($fp);
while ($row = fgetcsv($fp)) {
  echo implode(' | ', $row), PHP_EOL;
  // Or iterate $row, if you need:
  // foreach ($row as $cell) { do_something($cell); }
}

fclose($fp);

输出

r 0 c 0 | r 0 c 1 | r 0 c 2 | r 0 c 3 | r 0 c 4 | r 0 c 5
r 1 c 0 | r 1 c 1 | r 1 c 2 | r 1 c 3 | r 1 c 4 | r 1 c 5
r 2 c 0 | r 2 c 1 | r 2 c 2 | r 2 c 3 | r 2 c 4 | r 2 c 5
r 3 c 0 | r 3 c 1 | r 3 c 2 | r 3 c 3 | r 3 c 4 | r 3 c 5

【讨论】:

  • 我需要获取第一列以及该列的所有行(没有 OTHERS 列),在该循环中需要数组 $row[] 包含 row[1],row[2],row 中的数据[3]...row[24] 并放入基数,在下一次迭代中需要再次获取所有行的第 num.2 列,放入数组 $row[1],$row[2]... 和放入底座。
  • @MarkoAnastasijevic,如果不获取列的所有行,您将无法获取列。我为此添加了一个示例。
  • 好的。但在那种情况下,我不知道如何编写 sql 查询(插入)并在基础中插入数据。在基地我有 31 行 24 列。问题在于,因为在您的解决方案中,我有 31 个数组(没有编号),所有这些都有 24 个带有编号的值。
  • @MarkoAnastasijevic,你有关于交换行和单元格的想法吗?我添加了一个示例循环收集$fields,然后将它们与implode() 一起加入。您可以将 implode() 的结果传递到 SQL 查询中(当然要进行适当的转义!)。
  • 我尝试了那个解决方案,循环卡在 for ($r = 0; $r
【解决方案2】:

您可以使用如下所示的数组推送功能:

$csvFile = fopen("somefile.csv", "r");

        $firstline = true;
        $column1_array = array();
        $column2_array = array();

        while (($data = fgetcsv($csvFile, 2000, ",")) !== FALSE) {

            if (!$firstline) {

                if ($data['0'] != null || $data['0'] != "") {
                    array_push($column1_array, $data['0']);
                }
                if ($data['1'] != null || $data['1'] != "") {
                    array_push($column2_array, $data['1']);
                }
            }

            $firstline = false;
        }

        foreach ($column1_array as $value1) {

            foreach ($column2_array as $value2) {
                echo $value1 . $value2;
            }
        }

        // print_r($column1_array);
        // print_r($column2_array);

        fclose($csvFile);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 2019-06-01
    • 2019-10-14
    • 1970-01-01
    相关资源
    最近更新 更多