Dizelerden oluşan bir dizi çekmek ve bir CSV satırı dönmek için herhangi bir fonksiyon?

5 Cevap

Ben dizelerden oluşan bir dizi var ve onlardan bir CSV çizgi oluşturmak için bir yol istiyoruz. Gibi bir şey:

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

Will not work as the pieces may contain comma and double quotes.
Is there a PHP built in function that takes the pieces and return a well formatted CSV line?

Thanks,
Roge

5 Cevap

As far as I know there is no such built in function. The one I'm aware of is fputcsv that does exactly what you want but it does not return the CSV line, but writes it to a file.

<?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);
?>

Çoğu kez CSV hattı oluşturmak ve dosyaya yazmak istiyorum. Yani yukarıdaki fonksiyon yeterli olacaktır.

O fputcsv desteklemiyor gibi PHP4 için böyle bir fonksiyon yazmıştı. Ben sizinle paylaşmak olacak:

// 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";
}

Eğer bir dosyaya bu satırı yazmak istiyorsanız, fputcsv kullanabilirsiniz


Using the streams functionnality of PHP, it should be possible to write to a variable -- indeed, there's one guy in the comments of
str_getcsv who posted his implementation of 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" );
}
?>

Note : this code is not mine -- it's a copy-paste of the one posted by Ulf php.net üzerinde.

Hatta bunun için bir sınıf yazabilirsiniz

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);
 }

}

Eğer böyle useit olabilir

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

thats ;-)

Peki, bir şey yok well formatted CSV, orada olduğunu. Örneğin Open Office (noktalı virgül kullanır ;) varsayılan ayraç olarak, Excel, bir virgül (,) olmasını bekler iken. Ama gerçektir, no standard exists.

Dizi şöyle varsayarak:

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

Ya kullanımı, örneğin, farklı bir ayırıcı ile implode olabilir

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

Çalışmayan değilse, sadece bir virgül sınırlayıcısı ile patlayan önce, array_filter first and change the double quotes and comma via callback to whatever you think they should be ile Dize dizi çalıştırın:

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

Ama unutmayın, bu tüketen uygulama CSV okumak mümkün garanti etmez. Gerçekten onlar CSV ayrıştırma uygulamaya bağlıdır. Dediğim gibi: hayır standart.

Burada basit bir fputcsv uygulamasıdır:

$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);

I snarfed this elswhere on SO and posted here for faster reference, please bump/credit the original posting: Is my array to csv function correct?