как мне проанализировать CSV-файл, чтобы сначала получить имена столбцов, а затем относящиеся к нему строки?

#php #csv #fgetcsv

#php #csv #fgetcsv

Вопрос:

вот мой CSV

 column1,column2,column3,column4,column5
column1_row1,column2_row1,column3_row1,column4_row1,column5_row1
column1_row2,column2_row2,column3_row2,column4_row2,column5_row2
column1_row3,column2_row3,column3_row3,column4_row3,column5_row3
column1_row4,column2_row4,column3_row4,column4_row4,column5_row4
column1_row5,column2_row5,column3_row5,column4_row5,column5_row5
column1_row6,column2_row6,column3_row6,column4_row6,column5_row6
column1_row7,column2_row7,column3_row7,column4_row7,column5_row7
column1_row8,column2_row8,column3_row8,column4_row8,column5_row8
column1_row9,column2_row9,column3_row9,column4_row9,column5_row9
  

первая строка — это, конечно, имена столбцов. я попробовал fgetcsv(), но все, что это сделало бы, это отобразило все строки. вместо того, что я хочу. как я могу это сделать?

итак, если бы я поместил данные в массив в конце, я смог бы распечатать табличный формат данных, точно такой, как он показан в Excel.

Спасибо

это мой пример:

 $filename = "upload/sample.csv";
if (($handle = fopen($filename, 'r')) !== FALSE)
{
    while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) 
    {
       print_r($row);
     }
}
  

это мой вывод: (я поместил $ row в pre, чтобы я мог показать его)

 Array
(
    [0] => column1
    [1] => column2
    [2] => column3
    [3] => column4
    [4] => column5
column1_row1
    [5] => column2_row1
    [6] => column3_row1
    [7] => column4_row1
    [8] => column5_row1
column1_row2
    [9] => column2_row2
    [10] => column3_row2
    [11] => column4_row2
    [12] => column5_row2
column1_row3
    [13] => column2_row3
    [14] => column3_row3
    [15] => column4_row3
    [16] => column5_row3
column1_row4
    [17] => column2_row4
    [18] => column3_row4
    [19] => column4_row4
    [20] => column5_row4
column1_row5
    [21] => column2_row5
    [22] => column3_row5
    [23] => column4_row5
    [24] => column5_row5
column1_row6
    [25] => column2_row6
    [26] => column3_row6
    [27] => column4_row6
    [28] => column5_row6
column1_row7
    [29] => column2_row7
    [30] => column3_row7
    [31] => column4_row7
    [32] => column5_row7
column1_row8
    [33] => column2_row8
    [34] => column3_row8
    [35] => column4_row8
    [36] => column5_row8
column1_row9
    [37] => column2_row9
    [38] => column3_row9
    [39] => column4_row9
    [40] => column5_row9
)
  

Комментарии:

1. Что плохого в использовании fgetcsv и последующем просмотре каждой строки?

2. можете ли вы показать мне пример вашего метода? затем я укажу на то, что меня смущает

3. На самом деле у меня нет образца. Можете ли вы показать свой, а что не работает?

4. Поможет ли это, если вы установите значение enclosure (которое по умолчанию равно «) на что-то другое? Например, null или пустую строку или что-то в этом роде?

Ответ №1:

Для чтения всего этого сразу вы можете использовать:

 $csv = array_map("str_getcsv", file("file1.csv",FILE_SKIP_EMPTY_LINES));
$keys = array_shift($csv);
  

Чтобы превратить все строки в красивый ассоциативный массив, вы могли бы затем применить:

 foreach ($csv as $i=>$row) {
    $csv[$i] = array_combine($keys, $row);
}
  

Комментарии:

1. Как я могу использовать это с ; разделителем as?

2. Таким образом, вы не сможете работать с разделителями строк в ячейке.

3. @Michiel, как использовать другой разделитель: $file = file("file1.csv",FILE_SKIP_EMPTY_LINES); $csv = array_map("str_getcsv",$file, array_fill(0, count($file), ';'));

4. @mario это относится к моей любимой категории ответов. короче говоря, работает так, как рекламируется, и, что наиболее важно, он обучает меня новой функциональности

5. Обратите внимание, что это работает, только если все ваши строки данных имеют ту же длину, что и строка заголовка.

Ответ №2:

 // Opening the file for reading...
$fp = fopen('path_to_your_file.csv', 'r');

// Headrow
$head = fgetcsv($fp, 4096, ';', '"');

// Rows
while($column = fgetcsv($fp, 4096, ';', '"'))
{
    // This is a great trick, to get an associative row by combining the headrow with the content-rows.
    $column = array_combine($head, $column);

    echo $column['column1'];
}
  

Комментарии:

1. я попробовал ваш пример, но не получил выходных данных. знаете, почему это может быть?

2. работает, только если ваши имена столбцов ‘column1’, ‘column2’ и т.д. как в вашем примере. echo $column['the_name_of_your_column_in_the_headrow'];

3. да, я сделал, ничего не вышло, поэтому я сделал print_r из $ column и ничего . вот пример pastie.org/1796761

4. У вас включен error_reporting? Если нет, сделайте это и посмотрите, произошла ли ошибка. вы достигаете цикла while? вставьте die(x); для отладки в цикл, чтобы увидеть, выполняется ли он. Если нет, то файл пуст или указатель файла ($ fp) не задан (например, недопустимый путь).

5. Хорошее решение для всех, кто застрял на версии до 5.3

Ответ №3:

Я создал это быстрое решение, используя fgetcsv, работает нормально, и его легче читать и понимать. Затем весь результат сохраняется в массиве $ csv

 $csv = array();
$i = 0;
if (($handle = fopen($upload['file'], "r")) !== false) {
    $columns = fgetcsv($handle, 1000, ",");
    while (($row = fgetcsv($handle, 1000, ",")) !== false) {
        $csv[$i] = array_combine($columns, $row);
        $i  ;
    }
    fclose($handle);
}
  

Ответ №4:

Разве вы не можете сначала выполнить один fgetcsv вызов, чтобы получить заголовки, а затем запустить цикл, чтобы получить остальные?

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

 <?php
$row = 1;
if (($handle = fopen('test.csv', 'r')) !== FALSE)
{
    echo '<table>';

    // Get headers
    if (($data = fgetcsv($handle, 1000, ',')) !== FALSE)
    {
        echo '<tr><th>'.implode('</th><th>', $data).'</th></tr>';
    }

    // Get the rest
    while (($data = fgetcsv($handle, 1000, ',')) !== FALSE)
    {
        echo '<tr><td>'.implode('</td><td>', $data).'</td></tr>';
    }
    fclose($handle);
    echo '</table>';
}
?>
  

Комментарии:

1. @Sarmen: Добавлен пример. хотя я его не тестировал. дайте мне знать, если это сработает.

2. ps я добавил то, что пытался.

Ответ №5:

Похоже, что он может воспринимать все это как одну строку. Возможно, у вашего CSV-файла окончание строки отличается от положенного? По крайней мере, так это выглядит в ваших выходных данных. Если вы посмотрите на строку 1, столбец 5 в вашем результирующем массиве, он содержит окончание строки и столбец 1 в строке 2. И то же самое в остальных. Он считывает все это в одну строку.

Примечание: Если PHP неправильно распознает окончания строк при чтении файлов на компьютере Macintosh или созданных им, включение опции настройки во время выполнения auto_detect_line_endings может помочь решить проблему. — fgetscv

На какой платформе вы работаете? В любом случае, проверьте окончания строк.

Ответ №6:

Я изменил первый ответ, чтобы лучше обрабатывать разные разделители столбцов

 if (($handle = fopen("hdbsource/products_stock.csv", "r")) !== FALSE) {
    while (($csv[] = fgetcsv($handle, 1000, ',')) !== FALSE) {}
    fclose($handle);
}
$keys = array_shift($csv);

foreach ($csv as $i=>$row) {
    $csv[$i] = array_combine($keys, $row);
}
  

Комментарии:

1. У меня это не сработало.