php fgetcsv возвращает все строки

у меня есть следующий файл CSV:

upc/ean/isbn,item name,category,supplier id,cost price,unit price,tax 1 name,tax 1 percent,tax 2 name,tax 2 percent,quantity,reorder level,description,allow alt. description,item has serial number
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,

когда я делаю это:

if (($handle = fopen($_FILES['file_path']['tmp_name'], "r")) !== FALSE) 
{
    $data = fgetcsv($handle);
    var_dump($data);
}

Я получаю массив с 183 элементами, я ожидал бы получить только одну строку csv, но я получаю весь файл.

Я даже пробовал $data = fgetcsv($handle, 1000); и я получил тот же результат

6 ответов


это, скорее всего, проблема с окончанием строки. Попробуйте включить auto_detect_line_endings который попытается определить окончание строки файла.

ini_set('auto_detect_line_endings', true);

если это не решит проблему, то найти Тип линии разделители с помощью file:

$ file example.csv
example.csv: ASCII text, with CR line terminators

можно тут преобразование окончание строки. Я не уверен, какую ОС вы используете, но есть много программы для файл преобразование формата, например,dos2unix.


Это самое короткое решение, которое я мог придумать:

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

// get the first (header) line
$header = fgetcsv($fp);

// get the rest of the rows
$data = array();
while ($row = fgetcsv($fp)) {
  $arr = array();
  foreach ($header as $i => $col)
    $arr[$col] = $row[$i];
  $data[] = $arr;
}

print_r($data);

выход:

Array
(
    [0] => Array
        (
            [upc/ean/isbn] => 
            [item name] => Apple iMac
            [category] => Computers
            [supplier id] => 
            [cost price] => 10
            [unit price] => 12
            [tax 1 name] => 8
            [tax 1 percent] => 8
            [tax 2 name] => 10
            [tax 2 percent] => 10
            [quantity] => 10
            [reorder level] => 1
            [description] => Best computer
            [allow alt. description] => 
            [item has serial number] => 
        )

    [1] => Array
        (
            [upc/ean/isbn] => 
            [item name] => Apple iMac
            [category] => Computers
            [supplier id] => 
            [cost price] => 10
            [unit price] => 12
            [tax 1 name] => 8
            [tax 1 percent] => 8
            [tax 2 name] => 10
            [tax 2 percent] => 10
            [quantity] => 10
            [reorder level] => 1
            [description] => Best computer
            [allow alt. description] => 
            [item has serial number] => 
        )

    // ...

    [11] => Array
        (
            [upc/ean/isbn] => 
            [item name] => Apple iMac
            [category] => Computers
            [supplier id] => 
            [cost price] => 10
            [unit price] => 12
            [tax 1 name] => 8
            [tax 1 percent] => 8
            [tax 2 name] => 10
            [tax 2 percent] => 10
            [quantity] => 10
            [reorder level] => 1
            [description] => Best computer
            [allow alt. description] => 
            [item has serial number] => 
        )

)

попробуй:

 while (($data = fgetcsv($handle, 0, ',')) !== FALSE) {
    $columns = count($data);
 }

кроме того, вы можете попробовать использовать str_getcsv(file_get_contents(...))


получил ту же проблему, на Mac, с CSV-файлом, сгенерированным Microsoft Excel. Я выполнил команду больше на разных файлах, и кажется, что окончание строки отличается.

$ more excel.csv && more test.csv
aaa@aaa.fr^Mbbb@bbb.fr^Mccc@ccc.fr^M
ddd@ddd.fr
eee@eee.fr
fff@fff.fr

Я

ini_set('auto_detect_line_endings', true);

до

fgetcsv($handle, 0, ';')

и это работает. Принятый ответ правильный.


для чтения во всем CSV-файле сразу используйте:

$data = array_map("str_getcsv", file($fn));
var_dump($data);

хотя вам придется array_shift() в первой строке (если вы не используете столбец клавиши).


обходной путь для неспецифических окончаний строки:

$data = array_map("str_getcsv", preg_split('/[\r\n]+/', file_get_contents($fn)));
var_dump($data);

Если у вас есть опция, вернитесь к редактированию .csv-файл для включения окончаний строк стиля "Unix"...затем fgetcsv автоматически разбивает массив на окончания строк