Любая функция, чтобы взять массив строк и вернуть строку CSV? - PullRequest
2 голосов
/ 10 января 2010

У меня есть массив строк и я хочу создать из них строку CSV. Что-то вроде:

$CSV_line = implode(',',$pieces);

Не будет работать, так как части могут содержать запятую и двойные кавычки.
Есть ли встроенная функция PHP, которая берет кусочки и возвращает хорошо отформатированную строку CSV?

Спасибо
Roge

Ответы [ 5 ]

3 голосов
/ 10 января 2010

Если вы хотите записать эту строку в файл, вы можете использовать fputcsv


Используя функциональность потоков в PHP, должна быть возможность записи в переменную - действительно, в комментариях str_getcsv есть один парень, который опубликовал свою реализацию str_putcsv :

<?php
function str_putcsv($input, $delimiter = ',', $enclosure = '"') {
  // Open a memory "file" for read/write...
  $fp = fopen('php://temp', 'r+');
  // ... write the $input array to the "file" using fputcsv()...
  fputcsv($fp, $input, $delimiter, $enclosure);
  // ... rewind the "file" so we can read what we just wrote...
  rewind($fp);
  // ... read the entire line into a variable...
  $data = fread($fp, 1048576); // [changed]
  // ... close the "file"...
  fclose($fp);
  // ... and return the $data to the caller, with the trailing newline from fgets() removed.
  return rtrim( $data, "\n" );
}
?>

Примечание: этот код не мой - это копия, вставленная Ulf на php.net.

3 голосов
/ 10 января 2010

Вы могли бы даже написать класс, чтобы сделать это

class CSV_ARRAY {
 static public function arr_to_csv_line($arr) {
  $line = array();
  foreach ($arr as $v) {
   $line[] = is_array($v) ? self::arr_to_csv_line($v) : '"' . str_replace('"', '""', $v) . '"';
  }
  return implode(",", $line);
 }

 static public function arr_to_csv($arr) {
  $lines = array();
  foreach ($arr as $v) {
   $lines[] = self::arr_to_csv_line($v);
  }
  return implode("\n", $lines);
 }

}

Вы можете использовать это так

$csvlines = CSV_ARRAY::arr_to_csv_line($myarray);
file_put_contents($csvlines,"mycsv.csv");

Вот и все; -)

2 голосов
/ 10 января 2010

Насколько я знаю, такой встроенной функции нет. Мне известно, что fputcsv делает именно то, что вы хотите но он не возвращает строку CSV, а записывает ее в файл.

<?php

$pieces = array (
    'a,b,c,d',  // contains comma.
    '"1","2"'   // contains double quotes.
);

$fp = fopen('file.csv', 'w');

fputcsv($fp, $pieces); // "a,b,c,d","""1"",""2""" written

fclose($fp);
?>

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

Я написал одну такую ​​функцию для PHP4, поскольку она не поддерживает fputcsv. Я поделюсь этим с вами:

// If a value contains a comma, a quote, a space, a tab, a newline, or a linefeed,
// then surround it with quotes and replace any quotes inside it with two quotes
function make_csv_line($values)
{
    // iterate through the array ele by ele.
    foreach($values as $key => $value) 
    {
        // check for presence of special char.
        if (    (strpos($value, ',')  !== false) || (strpos($value, '"')  !== false) ||
            (strpos($value, ' ')  !== false) || (strpos($value, "\t") !== false) ||
            (strpos($value, "\n") !== false) || (strpos($value, "\r") !== false)) 
        {
            // if present, surround the ele in quotes..also replace 
            // already existing " with ""
            $values[$key] = '"' . str_replace('"', '""', $value) . '"';
        }
    }

    // now create the CSV line by joining with a comma, also put a \n at the end.
    return implode(',', $values) . "\n";
}
0 голосов
/ 02 сентября 2013

Вот более простая реализация fputcsv:

$stdout = fopen('php://output','w'); // 'stdout' is for CLI, 'output' is for Browser
fputcsv($stdout, array('val,ue1','val"ue2','value3','etc'));
fflush($stdout); // flush for fun :)
fclose($stdout);

Я остановил это на SO и разместил здесь для более быстрой ссылки, пожалуйста, увеличьте / отметьте оригинальную публикацию: Правильно ли работает мой массив с csv?

0 голосов
/ 10 января 2010

Ну, дело в том, что нет хорошо отформатированного CSV. Например, Open Office использует точку с запятой (;) в качестве разделителя по умолчанию, а Excel ожидает, что это будет запятая (,). Но факт в том, что стандарта не существует .

Предполагается, что массив выглядит примерно так:

Array
    0 => Some string
    1 => Some other string, with comma
    2 => And a third one with "double quotes" 
);

Вы можете использовать implode с другим разделителем, например,

$delimiter = chr(9); // Tab
$delimiter = ';'     // Semicolon. Excel's default
$delimiter = '|'     // Pipe
$delimiter = "','";  // Comma plus Single Quote

Если это не работает, сначала запустите массив String через array_filter и измените двойные кавычки и запятую с помощью обратного вызова на , как вы думаете, они должны быть , прежде чем взорваться с просто запятая:

$csv = implode(',' array_filter($array, 'my_csv_prepare'));

Но имейте в виду, это не гарантирует, что ваше приложение-потребитель сможет читать CSV. Это действительно зависит от того, как они реализовали разбор CSV. Как я уже сказал: нет стандарта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...