Skip to content
Advertisement

PHP – fgetcsv loop for get data from csv file column by column

I have a CSV file with 31 columns and 24 rows. I need with fgetcsv (or maybe another solution) to pass in the CSV and get data column by column. I have one solution:

 // { ?
  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);  
}

The for loop is working but $data[$col] only gets data from the first column of the CSV, it doesn’t get data from $data[$col] when $col is 2, 3, 4, …, 31.

Where did I make a mistake, and what is the problem? The code looks okay to me, but I think that I don’t know something about the fgetcsv function.

max is filesize of CSV, fgetcsv see that like max size of file. No matter what is in fgetcsv they see just first column, not loop every time when $col changes.

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]')"

Advertisement

Answer

In your code:

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

you are trying to fetch all rows from the file 32 times. The first iteration fetches all the rows from the file, since the while loop ends when fgetcsv returns false (when there is no more data to read).

I need with fgetcsv(or maybe other solution) to pass in csv and get data column by column.

You can not read data column by column, since the file is read line by line, and the lines represent the table rows. If you want to iterate the table data by columns, you can read the entire table into an array, then exchange rows and cells:

$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)
}

So you don’t need the outer loop iterating the column “indices”, as fgetcsv already fetches an array for the next row where the items contain the cell values:

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

At least, put the loop into the while loop that fetches the rows. If you want to iterate the cells, iterate the value returned by fgetcsv.

Example

$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);

Output

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
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement