fputcsv

(PHP 5 >= 5.1.0RC1)

fputcsv -- 将行格式化为 CSV 并写入文件指针

说明

int fputcsv ( resource handle [, array fields [, string delimiter [, string enclosure]]] )

fputcsv() 将一行(用 fields 数组传递)格式化为 CSV 格式并写入由 handle 指定的文件。返回写入字符串的长度,出错则返回 FALSE

可选的 delimiter 参数设定字段分界符(只允许一个字符)。默认为逗号:,

可选的 enclosure 参数设定字段字段环绕符(只允许一个字符)。默认为双引号:"

例子 1. fputcsv() 例子

<?php

$list
= array (
    
'aaa,bbb,ccc,dddd',
    
'123,456,789',
    
'"aaa","bbb"'
);

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

foreach (
$list as $line) {
    
fputcsv($fp, split(',', $line));
}

fclose($fp);
?>

注: 如果碰到 PHP 在读取文件时不能识别 Macintosh 文件的行结束符,可以激活 auto_detect_line_endings 运行时配置选项。

参见 fgetcsv()


add a note add a note User Contributed Notes
03-Aug-2006 08:09
It's unrealistic to require the field enclosure to be one character because it's very common to have "empty string" as the field delimiter (especially when TAB is used as field delimiter).

I tried to use "\0" as the field enclosure, hoping that'd be interpreted as an empty string, but fputcsv (in PHP5) translated it into literal.

By the way, fputcsv wrongly adds the field enclosures whenever a field contains a space. The expected behavior should be adding the field enclosures when a field contains a field delimiter.
heather at heathercash dot com
26-Sep-2005 07:18
Here is an adaptation to boonerunner's function for fputcsv.
It uses a 2-dimensional array.
Each sub-array is a line in the csv file which then ends up being seperated by commas.

function fputcsv($filePointer,$dataArray,$delimiter=",",$enclosure="\""){
   // Write a line to a file
   // $filePointer = the file resource to write to
   // $dataArray = the data to write out
   // $delimeter = the field separator
    
   // Build the string
   $string = "";
 
   // for each array element, which represents a line in the csv file...
   foreach($dataArray as $line){

       // No leading delimiter
       $writeDelimiter = FALSE;
      
       foreach($line as $dataElement){
           // Replaces a double quote with two double quotes
           $dataElement=str_replace("\"", "\"\"", $dataElement);
          
           // Adds a delimiter before each field (except the first)
           if($writeDelimiter) $string .= $delimiter;
          
           // Encloses each field with $enclosure and adds it to the string
           $string .= $enclosure . $dataElement . $enclosure;
          
           // Delimiters are used every time except the first.
           $writeDelimiter = TRUE;
       }
       // Append new line
       $string .= "\n";

   } // end foreach($dataArray as $line)

   // Write the string to the file
   fwrite($filePointer,$string);
}
boonerunner at hotmail dot com
16-Sep-2005 10:47
Here is an adaption of the above code that adds support for double quotes inside a field. (One double quote is replaced with a pair of double quotes per the CSV format).

<?php
 
function fputcsv($filePointer,$dataArray,$delimiter,$enclosure)
  {
 
// Write a line to a file
  // $filePointer = the file resource to write to
  // $dataArray = the data to write out
  // $delimeter = the field separator
 
  // Build the string
 
$string = "";
 
 
// No leading delimiter
 
$writeDelimiter = FALSE;
  foreach(
$dataArray as $dataElement)
   {
  
// Replaces a double quote with two double quotes
  
$dataElement=str_replace("\"", "\"\"", $dataElement);
  
  
// Adds a delimiter before each field (except the first)
  
if($writeDelimiter) $string .= $delimiter;
  
  
// Encloses each field with $enclosure and adds it to the string
  
$string .= $enclosure . $dataElement . $enclosure;
  
  
// Delimiters are used every time except the first.
  
$writeDelimiter = TRUE;
   }
// end foreach($dataArray as $dataElement)
 
  // Append new line
 
$string .= "\n";
 
 
// Write the string to the file
 
fwrite($filePointer,$string);
  }
?>
twebb at boisecenter dot com
21-Jan-2005 09:54
What about cells that span multiple lines?  This function allows for cells to contain newlines:

function fputcsv($handle, $row, $fd=',', $quot='"')
{
   $str='';
   foreach ($row as $cell)
   {
     $cell = str_replace($quot, $quot.$quot, $cell);
        
     if (strchr($cell, $fd) !== FALSE || strchr($cell, $quot) !== FALSE || strchr($cell, "\n") !== FALSE)
     {
         $str .= $quot.$cell.$quot.$fd;
     }
     else
     {
         $str .= $cell.$fd;
     }
   }

   fputs($handle, substr($str, 0, -1)."\n");

   return strlen($str);
}

I found this reference on the web:
http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm
drew at zitnay dot com
23-Nov-2004 01:42
I found the following problems with the below function:

- when calling str_replace(), you must assign $cell the return value or nothing gets saved

- when using strchr(), you should explicitly check !== FALSE, or it'll treat a return value of 0 (found the character at string position 0) as FALSE

- Excel seems to quote not only fields containing commas, but fields containing quotes as well, so I've added another strchr() for quotes; I'm not saying Microsoft knows the correct way for sure, but it seems reasonable to me

- the original function put a space after each comma; that might be legal, I don't know, but I've never seen it (and I don't think it is, because then how would you indicate you wanted a field to start with a space other than by quoting it?)

- the original function didn't correctly return the length of the data outputted

Here's the function, fixed up a bit:

function fputcsv($handle, $row, $fd=',', $quot='"')
{
   $str='';
   foreach ($row as $cell) {
       $cell=str_replace(Array($quot,        "\n"),
                         Array($quot.$quot,  ''),
                         $cell);
       if (strchr($cell, $fd)!==FALSE || strchr($cell, $quot)!==FALSE) {
           $str.=$quot.$cell.$quot.$fd;
       } else {
           $str.=$cell.$fd;
       }
   }

   fputs($handle, substr($str, 0, -1)."\n");

   return strlen($str);
}

Drew
arthur.at.korn.ch
20-Nov-2004 01:56
The function in the prior comment doesn't escape quotes in fields, here mine:

function fputcsv($handle, $row, $fd=',', $quot='"')
{
   $str='';
   foreach ($row as $cell) {
       str_replace(Array($quot,        "\n"),
                   Array($quot.$quot,  ''),
                   $cell);
       if (strchr($cell, $fd)) {
           $str.=$quot.$cell.$quot.$fd.' ';
       } else {
           $str.=$cell.$fd.' ';
       }
   }

   fputs($handle, substr($str, 0, -2)."\n");

   return $str-1;
}
arthur at mclean dot ws
12-Nov-2004 06:10
Here's a simplistic fputcsv function that you can use until the real one gets out of CVS:

function fputcsv($filePointer, $dataArray, $delimiter, $enclosure){
     // Write a line to a file
     // $filePointer = the file resource to write to
     // $dataArray = the data to write out
     // $delimeter = the field separator
    
     // Build the string
     $string = "";
     $writeDelimiter = FALSE;
     foreach($dataArray as $dataElement){
       if($writeDelimiter) $string .= $delimiter;
       $string .= $enclosure . $dataElement . $enclosure;
       $writeDelimiter = TRUE;
       } // end foreach($dataArray as $dataElement)
    
     // Append new line
     $string .= "\n";
    
     // Write the string to the file
     fwrite($filePointer, $string);
    
     } // end function fputcsv($filePointer, $dataArray, $delimiter)