PHP эффективно записывает и выводит файлы csv с помощью fputcsv

При записи файлов .csv я использую fputcsv следующим образом:

- open a temporary file $f = tmpfile();
- write content to file using fputcsv($f,$csv_row);
- send appropriate headers for attachment
- read file like this:

# move pointer back to beginning 
rewind($f);

while(!feof($f))
    echo fgets($f);

# fclose deletes temp file !
fclose($f);

Другой подход:

- open file $f = fopen('php://output', 'w');
- send appropriate headers for attachment
- write content to file using fputcsv($f,$csv_row);
- close $f stream

У меня вопрос: как лучше всего выводить данные быстрее и с учетом ресурсов сервера?

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

Второй метод использует меньше операций записи и, как мне кажется, будет выводить медленнее.

С нетерпением жду вашего мнения по этому поводу.

Спасибо.


person B Paul    schedule 31.08.2012    source источник
comment
Дело не во мнениях. Мы не думаем, что один из них быстрее. Попробуйте протестировать оба подхода, и вы узнаете, какой из них быстрее.   -  person Berry Langerak    schedule 31.08.2012
comment
@BerryLangerak Да, вы правы. Я попробую протестировать это и опубликовать результаты.   -  person B Paul    schedule 31.08.2012


Ответы (2)


fpassthru () будет делать то, что вы делаете, на более низком уровне. Используйте это так:

# move pointer back to beginning 
rewind($f);

while(fpassthru($f) !== false);

# fclose deletes temp file !
fclose($f);

Даже если это может быть файл csv, нет необходимости ограничивать себя функциями csv, если только вы не генерируете файл во время вывода.

Вероятно, вы могли бы увидеть прирост производительности, если бы передавали CSV для вывода, а не в файл.

person Lucas Green    schedule 31.08.2012
comment
Я создаю из базы данных большой CSV-файл. Всегда быстрее использовать встроенные функции, предлагаемые php. Спасибо за fpassthru ()! Я кое-что узнал сегодня :). - person B Paul; 31.08.2012

Зачем вам нужно записывать содержимое csv в выходной поток файла tmp / php?

Вам просто нужно напрямую отобразить содержимое csv, не должно быть никаких файловых операций.

  • отправить соответствующие заголовки для вложения
  • повторить содержимое CSV.

header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

foreach ($csv_rows as $csv_row) {
  echo $csv_row;
}
exit;
person xdazz    schedule 31.08.2012
comment
Потому что он использует fputcsv () для преобразования произвольного массива в строку CSV. В PHP нет функции stringtocsv, afaik. - person Berry Langerak; 31.08.2012
comment
Если $csv_row является массивом, вам просто нужно взорвать его с помощью разделителя. echo implode(',', $csv_row)."\n";. - person xdazz; 31.08.2012
comment
На самом деле CSV очень сложен, и вы сильно его недооцениваете. Например, разделители должны быть экранированы, как и разделитель. Если значение из массива - foo, bar, baz, идея взрыва сгенерирует поврежденный файл CSV. Это сложнее, чем вы думаете. - person Berry Langerak; 31.08.2012
comment
@BerryLangerak Я знаю это. Но вы всегда можете сбежать самостоятельно, что несложно. - person xdazz; 31.08.2012
comment
Да, это сложная вещь. Но во что бы то ни стало; попробуй. - person Berry Langerak; 31.08.2012
comment
@berrylangerak Я хочу сказать, что вы просто не можете использовать временный файл, если вы будете искать на этом сайте, я уверен, что есть ответы, которые расскажут вам, как преобразовать массив в строку csv. - person xdazz; 31.08.2012
comment
@xdazz Зачем изобретать велосипед, если у тебя есть хороший? fputcsv намного лучше и быстрее, чем экранирование вручную, особенно для больших файлов. Берри Лангерак ​​права. - person B Paul; 31.08.2012