Как я могу изменить окончания строк, используемые fputcsv?

Я создаю CSV-файл для загрузки нашим клиентом, используя

$output = fopen('php://output', 'w'); 

и используя fputcsv() для записи данных в файл CSV, который загружается клиентом.

Я запускаю PHP на Linux, и поэтому окончание строк не интерпретируется многими приложениями Windows.

Я мог бы написать CSV-файл в каталог на сервере, прочитать его обратно и выполнить str_replace() с \n до \r\n , но это кажется довольно неуклюжим способом решения проблемы. Есть ли способ выполнить преобразование без создания физического файла?

Для этого вы можете использовать фильтры потока. Этот пример записывается в физический файл, но он должен отлично работать и для php://output .

 // filter class that applies CRLF line endings class crlf_filter extends php_user_filter { function filter($in, $out, &$consumed, $closing) { while ($bucket = stream_bucket_make_writeable($in)) { // make sure the line endings aren't already CRLF $bucket->data = preg_replace("/(?<!\r)\n/", "\r\n", $bucket->data); $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } return PSFS_PASS_ON; } } // register the filter stream_filter_register('crlf', 'crlf_filter'); $f = fopen('test.csv', 'wt'); // attach filter to output file stream_filter_append($f, 'crlf'); // start writing fputcsv($f, array('1 1', '2 2')); fclose($f); 

Не уверен, что вы можете сделать это с помощью самого PHP. Возможно, есть способ изменить EOL для EF для записи файлов, но, вероятно, зависит от системы. У вас нет системы Windows, которую вы могли бы пинговать, не так ли? 😉

Что касается реального решения, вместо str_replace по очереди вы можете использовать программу Linux unix2dos (обратная к dos2unix ) при условии, что вы ее установили:

 fputcsv($fh ...) exec("unix2dos " . escapeshellarg($filename)); 
  1. Создайте файл с окончанием строки \ n на машине Linux
  2. FTP файл как ASCII от машины Linux к машине Windows
  3. Вуаля! Все конечные строки теперь находятся в файле на машине Windows

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

 function output($buffer) { return str_replace("\r", "\r\n", $buffer); } ob_start('output'); fputcsv(....);