PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

fgets> <fgetc
Last updated: Fri, 03 Oct 2008

view this page in

fgetcsv

(PHP 4, PHP 5)

fgetcsvファイルポインタから行を取得し、CSVフィールドを処理する

説明

array fgetcsv ( resource $handle [, int $length [, string $delimiter [, string $enclosure [, string $escape ]]]] )

fgets() に動作は似ていますが、 fgetcsv() は行を CSV フォーマットのフィールドとして読込み処理を行い、 読み込んだフィールドを含む配列を返すという違いがあります。

パラメータ

handle

ファイルポインタは有効なものでなければならず、また fopen(), popen(), もしくは fsockopen() で正常にオープンされたファイルを指している必要があります。

length

(行末文字を考慮して) CSV ファイルにある最も長い行よりも大きい必要があります。 PHP 5 でオプションになりました。このパラメータを省略 (もしくは PHP 5.0.4 かそれ以降で 0 を設定) すると、 最大行長は制限されません。この場合、若干動作が遅くなります。

delimiter

フィールドのデリミタ (1 文字のみ) を設定します。 デフォルトはカンマです。

enclosure

フィールド囲いこみ文字 (1 文字のみ) を設定します。 デフォルトはダブルクォーテーションマークです。

escape

エスケープ文字 (1 文字のみ) を設定します。 デフォルトはバックスラッシュ (\) です。

返り値

読み込んだフィールドの内容を含む数値添字配列を返します。

注意: CSV ファイルの空行は null フィールドを一つだけ含む配列として返され、 エラーにはなりません。

注意: マッキントッシュコンピュータ上で作成されたファイルを読み込む際に、 PHP が行末を認識できないという問題が発生した場合、 実行時の設定オプションauto_detect_line_endings を有効にする必要が生じるかもしれません。

fgetcsv() は、ファイルの終端に達した場合を含めてエラー時に FALSE を返します。

変更履歴

バージョン 説明
5.3.0 escape パラメータが追加されました。
4.3.5 fgetcsv() はバイナリセーフとなりました。
4.3.0 enclosure パラメータが追加されました。

例1 CSV ファイルの全てのコンテンツを読み込み、表示する

<?php
$row 
1;
$handle fopen("test.csv""r");
while ((
$data fgetcsv($handle1000",")) !== FALSE) {
    
$num count($data);
    echo 
"<p> $num fields in line $row: <br /></p>\n";
    
$row++;
    for (
$c=0$c $num$c++) {
        echo 
$data[$c] . "<br />\n";
    }
}
fclose($handle);
?>

注意

注意: この関数はロケール設定を考慮します。もし LANG が例えば en_US.UTF-8 の場合、 ファイル中の 1 バイトエンコーディングは間違って読み込まれます。



fgets> <fgetc
Last updated: Fri, 03 Oct 2008
 
add a note add a note User Contributed Notes
fgetcsv
marcos at yuniti com
09-Sep-2008 01:35
Smarter/better fgetcsv functions, acceptying multiple-character delim, enclosure, and escape.

<?php
define
('BUFFER_READ_LEN', 4096);
function
fgetcsv_ex($file_handle, $delim = ',', $enclosure = '"', $escape = '"') {
   
$fields = null;
   
$fldCount = 0;
   
$inQuotes = false;
   
   
$complete = false;
   
$search_chars_list = array('\r\n', '\n', '\r');
    if (
$delim && ($delim != '') )
     
$search_chars_list[] = $delim;
    if (
$enclosure && ($enclosure != '') )
    {
     
$search_chars_list[] = $enclosure;
     
$enclosure_len = strlen($enclosure);
    }
    else
     
$enclosure_len = 0;

    if (
$escape && ($escape != '') )
    {
     
$search_chars_list[] = $escape;
     
$escape_len = strlen($escape);
    }
    else
     
$escape_len = 0;
   
$search_regex = '/' . implode('|', $search_chars_list) . '/';

   
$cur_pos = 0;
   
$line = '';
   
$cur_value = '';
   
$in_value = false;
   
$last_value = 0;
    while ( !
$complete )
    {
     
$read_result = fread($file_handle, BUFFER_READ_LEN);
      if (
$read_result )
       
$line .= $read_result;
      else if (
strlen($line) == 0 )
        return
null;
      else
       
$line .= "\n";

     
$line_len = strlen($line);
     
      while (
true )
      {
        if (!
preg_match($search_regex, $line, $matches, PREG_OFFSET_CAPTURE, $cur_pos))
        {
          if (
$read_result) //need more chars
           
break;
          else
            return
null; //Incomplete file
       
}
        else
        {
         
$non_escape = false;
         
$cur_char = $matches[0][0];
         
$cur_len = strlen($cur_char);
         
$new_pos = $matches[0][1];
          if ((
$enclosure == $escape) && $in_value && ($cur_char == $escape))  //Escape char = enclosure char special handling
         
{
            if ((
$new_pos + $cur_len + $enclosure_len) >= $line_len//We need the next char
             
break;
           
           
$next_char = substr($line, $new_pos + $cur_len, $enclosure_len);
            if ( (!
$enclosure) || ($next_char != $enclosure) )
             
$non_escape = true;
          }
           
         
$cur_pos = $new_pos;
          if (
$in_value && (! $non_escape) )
          {
           
$cur_value .= mb_substr($line, $last_value, $cur_pos - $last_value);
            if (
$cur_char == $escape//Skip escape char
             
$cur_pos += $escape_len;
           
$last_value = $cur_pos;
          }
          else if ( (
$cur_char == "\n" ) || ( $cur_char == "\r" ) || ( $cur_char == "\r\n" ) )
          {
             
$blank_start_lines = ( $cur_pos == 0 );
              ++
$cur_pos;
             
$cur_pos = $cur_pos + strspn($line, "\n\r", $cur_pos);
              if ( !
$blank_start_lines )
              {
               
$complete = true;
                break;
              }
              else
              {
               
$last_value = $cur_pos;
                continue;
              }
          }
          else if (
$cur_char == $delim )
          {
            if (
is_null($fields) )
             
$fields = array();
           
$fields[] = $cur_value . trim(mb_substr($line, $last_value, $cur_pos - $last_value));
           
$last_value = $cur_pos + $cur_len;
           
$cur_value = '';
          }
          else if (
$cur_char == $enclosure )
          {
            if (
$in_value )
             
$cur_value .= mb_substr($line, $last_value, $cur_pos - $last_value);
           
$last_value = $cur_pos + $cur_len;
           
$in_value = ! $in_value;
          }
         
$cur_pos += $cur_len;
        }
      }
  }
 
 
fseek($file_handle, $cur_pos - strlen($line), SEEK_CUR);
  return
$fields;
}
?>
hunzinker at gmail dot com
28-Aug-2008 12:45
Here is another function that splits the rows of a CSV file and uses a comma as its delimiter. The function also ignores commas inside of double quotations and removes any double quotes and ultimately prints out the data into a table. If you need to keep the double quotes you'll need to edit the code.

The function takes an array as an argument. The array I pass into the function contains the display name and CSV file name.

Enjoy!

<?php
   
/**
     * Function to print out data from an uploaded CSV file into a table.
     *
     * @param array $data
     * @return
     */
   
function printCSV ($data) {
        if (
is_array($data)) {
           
// open the csv file and read it
           
$dataFile = 'documents/courses/' . $data['course_file']; // change per setup - $data['course_file'] = CSV file name
           
$open = fopen($dataFile, 'r');
           
$csv = fread($open, filesize($dataFile));
           
            print
"<h2>" . $data['name'] . "</h2>"; // optional
            // split up the rows
           
$csv = preg_split('/[\r\n]/', $csv);
           
           
$csvData = array();
           
$i = 0;
            foreach (
$csv as $line) {
               
// splits lines with a comma but ignores a comma wrapped with double quotes
               
$csvData[$i] = preg_split('/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/', $line);
               
$i++;
            }
            print
"<table width='60%' cellpadding='0' cellspacing='0' class='course-table'>";
                for (
$j = 0; $j < count($csvData); $j++) {
                   
// print the first line with <th> tags
                   
if ($csvData && $j == 0) {
                        print
"<tr>";
                        for (
$k = 0; $k < count($csvData[$j]); $k++) {
                           
// remove the double quotes
                           
if (preg_match('/\"/', $csvData[$j][$k])) {
                                print
"<th>" . trim($csvData[$j][$k], '"')  . "</th>"; // edit if you wish to keep the double quotes
                           
} else {
                                print
"<th>" . $csvData[$j][$k] . "</th>";
                            }
                        }
                        print
"</tr>";
                   
// print the rest with <td> tags
                   
} else {
                        print
"<tr>";
                        for (
$k = 0; $k < count($csvData[$j]); $k++) {
                           
// remove the double quotes
                           
if (preg_match('/\"/', $csvData[$j][$k])) {
                                print
"<td>" . trim($csvData[$j][$k], '"')  . "</td>"; // edit if you wish to keep the double quotes
                           
} else {
                                print
"<td>" . $csvData[$j][$k] . "</td>";
                            }
                        }
                        print
"</tr>";
                    }
                }
            print
"</table>";
        } else {
            return
false;
        }
    }
?>
Dave
01-Aug-2008 02:03
If you want to get your CSV rows (in this case a file posted from a form) into one big array, you can use this code.  You may have to play around with the ord() and explode separators depending on your line endings.  You can change to the commented out explode to use " delimiter.

<?php

if( $_FILES['file']['tmp_name'] )
{
  
$csv_rows=Array();
  
$csv="";
  
$handle = fopen($_FILES['file']['tmp_name'], "r");

  
//load char by char, to replace line endings       
  
while($data = fgetc($handle)) 
   { 
      if(
ord($data)==13)
      {
       
$csv.="\r\n";
      }
      else
      {
       
$csv.=$data;
      }
    }
   
fclose($handle);
           
   
$csv_lines=explode("\r\n", $csv);

    foreach(
$csv_lines as $line)
    {
     
$csv_rows[]=explode(",", $line);
     
//or ltrim(rtrim(explode('","', $line),'"'),'"') for delimited fields
   
}
}

?>
Vijayaraj Nagarajan
11-Jul-2008 05:40
I used this simple php code for reading a csv file with two columns (without column heads) and generating an associative array out of it...

<?php
#reads the file data.csv
$data=file("data.csv", FILE_IGNORE_NEW_LINES);
#explodes each line contents and assigns the values to an array
foreach ($data as $line)
{
  
$mparts=explode(',',$line);
  
#pushes the array values in to an associative array
  
$dataarray[$mparts[0]]=$mparts[1];
}
#prints the values of the new associative array
print_r($dataarray);
?>
tanthalas at magickfox dot org
30-May-2008 04:33
Hey everybody...

I know that a lot of people have written code to parse CSVs etc... I have written one which I believe is a lot smaller and faster than those listed here...

<?php

   
/*

        class.parser.php

        Dynamically parses a CSV file and returns the values as array for processing.

    */

   
class parser {

        function
doParse($csvFile,$sep) {
           
$csvFile = file($csvFile);
            foreach (
$csvFile as $key=>$value) {
               
$v = explode($sep,$value);
                foreach (
$v as $kk=>$lineItem) {
                   
$csv[$key][$kk] = trim(trim($lineItem),"\"");
                }
            }
            return
$csv;    // an associative array of the csv.           
       
}

        function
dumpCSV($data,$sep,$heading = "") {
           
/*

                    build the "csv" from a 2 dimensional array
                    $result = $parser->dumpCSV($data,",",$heading);
                    where $data is an array formed similar to doParse (see above), and $heading
                    is the heading line for the CSV (titles etc).... Something like
                    $heading = "\"Booking Number\",\"Booking Date\"\n";
                    if you do not want/need a headling line, do not include $heading

            */
           
unset($message);
           
$message[] = $heading;
           
$x = 0;
            foreach (
$data as $key=>$v) {
                unset(
$tempmsg);
                foreach (
$v as $item) {
                   
$tempmsg .= "\"".$item."\"".$sep;
                }
               
$message[$x] = trim($tempmsg,",");        // gets rid of excess , @ the end of each line.
               
$x++;
            }
           
//print_r($message);
            // calculate accurate file size for the "downloaded file"
           
foreach ($message as $line) {
               
$bytes .= strlen($line);
            }
            return
$message;
        }

        function
downloadCSV($data,$filename) {
           
header ("Content-Type: application/vnd.ms-excel");
           
header ("Content-disposition: attachment; filename=\"".$filename.".csv\"");
           
header ("Content-length: $bytes");
            foreach (
$data as $line) {
                echo
$line."\n";
            }
        }

        function
searchCSVKey($data,$searchkey) {
            foreach (
$data as $key=>$v) {
                foreach (
$v as $item) {
                    if (
$item == $searchkey) {
                       
$returnvalue             = $data[$key];
                       
$returnvalue['line']    = $key;
                        break
2;
                    }
                }
            }
            if (
$returnvalue == "") {
               
$returnvalue['0']                 = "NULL";
               
$returnvalue['line']            = 0;
            }
            return
$returnvalue;
        }

        function
getPartialCSVAlpha($data,$start) {
           
// gets from $start to the end of the CSV. useful for searching
           
for ($x = $start + 1; $x <= count($data); $x++) {
               
$d[] = $data[$x];
            }
            return
$d;
        }

        function
getPartialCSVOmega($data,$finish) {
           
// 1 to the $finish of the CSV and return
           
for ($x = 0; $x <     $finish; $x++) {
               
$d[] = $data[$x];
            }
            return
$d;
        }

        function
getSection($data,$startSearch,$finishSearch) {
           
$r1             = $this->searchCSVKey($data,$startSearch);
           
$data            = $this->getPartialCSVAlpha($data,$r1['line']);        // gets rid of the first section not needed.
           
$r2             = $this->searchCSVKey($data,$finishSearch);
           
$data            = $this->getPartialCSVOmega($data,$r2['line']);    // sections down the CSV.
           
return $data;
        }
       
        function
getSectionByLine($data,$start,$finish) {
            for (
$x = $start; $x <= $finish; $x++) {
               
$output[] = $data[$x];
            }
            return
$output;
        }

        function
addValues3($array1,$array2) {
            foreach (
$array1 as $key1=>$val1) {
                foreach (
$val1 as $i=>$v) {
                    if ((
is_numeric($array1[$key1][$i]) == TRUE) && ($i > 1)) {
                       
$output[$key1][$i] = floatval($array2[$key1][$i]) + floatval($array1[$key1][$i]);
                    } else {
                       
$output[$key1][$i] = $array1[$key1][$i];
                    }
                }
            }
            return
$output;
        }

    }

   
// </eof> //

?>

Hope it helps all :)
Verlustmeldung at gmx dot de
24-May-2008 09:59
i wrote a decent litte class which is able to import excel 2003 .csv files kickass fast and easy. havent tested it with other excel versions, but they should work as well.

<?php
class read_csv {
    function
read_csv () {
       
// nothing
   
}

    function
read_csv_run($f="") {
        if (
$f AND is_file($f) ) {
           
// set excel type delimiter, etc
           
$delimiter = ';';
           
$enclosure = '"';

           
// read file & parse
           
$input = file($f);
           
$csv = array();
            foreach (
$input as $key => $value ) {
               
// rtrim crap at the end of the string
               
$tmp = explode($delimiter,rtrim($value));

               
// parse
               
$in_quote = false;
               
$arr = array();
                foreach (
$tmp as $key => $value ) {
                    if (
$in_quote ) {
                        if (
$this->read_csv_has_quote($value,$enclosure) ) {
                           
$in_quote = false;
                           
$value = substr_replace($value,'',-1,1);
                        }
                       
$key = (count($arr)-1);
                       
$arr[$key] .= $delimiter.$value; // continue last array element
                   
} else {
                        if (
$this->read_csv_has_quote($value,$enclosure) ) {
                           
$in_quote = true;
                           
$value = substr_replace($value,'',0,1);
                        } else if (
substr($value,0,1) == $enclosure AND substr($value,-1,1) == $enclosure ) {
                           
// string is quoted, remove quotes
                           
$value = substr_replace($value,'',0,1); // start
                           
$value = substr_replace($value,'',-1,1); // end
                       
}
                       
$arr[] = $value; // append to array
                   
}               
                }

                foreach (
$arr as $key => $value ) {
                   
$arr[$key] = str_replace($enclosure.$enclosure,$enclosure,$value);
                }

               
// append to array
               
$csv[] = $arr;
            }
// end foreach
           
           
echo nl2br(print_r($csv,1));
        }
// end if
   
} // end func
   
   
function read_csv_has_quote ($str="",$enc="") {
       
$c = substr_count($str,$enc);
        if (
stristr(($c/2),".") ) {
            return
true;
        }
    }
}
// end class

$csv =& new read_csv();
$csv->read_csv_run("katalog_excel_D.csv");
?>

mfg RR
skirkendall at NOSPAM dot dsl-only dot net
01-May-2008 03:55
The array_flip() function is handy for converting column names to column numbers.  Assuming the first row contains column names, you can simply read it via fgetcsv(); this will give you a number-indexed array of column names.  Applying array_flip() converts that into a name-indexed array of column numbers.

The following example does this, and assumes that two of the columns are named "animal" and "sound" but does not make any assumption about where those columns are.

$fp = fopen($url, "r");
$names = array_flip(fgetcsv($fp, 1000));
while (($values = fgetcsv($fp, 1000)) !== FALSE) {
    print "The ".$values[$names["animal"]]." says ".$values[$names["sound"]].".\n";
}
fclose($fp);
Philipp
19-Apr-2008 08:31
With this modification the last item will be added to the array: "a","b","c" is transformed to array("a","b","c") - old function returned array("a","b")

<?php
/*
    Modified function from user comment by Marcos Boyington / 06-Mar-2008 03:08
   
    This is a pretty useful update/modification to the fgetcsv function, which allows for:
    * Multiple-character/multibyte delim/enclosure/escape
    * Multibyte values
    * Escape character specification in < PHP5
    * Escape character = delim character
    * Direct reading from files without bloating memory too much
*/
define('BUFFER_READ_LEN', 4096);
function
fgetcsv_ex($file_handle, $delim = ',', $enclosure = '"', $escape = '"') {
   
$fields = null;
   
$fldCount = 0;
   
$inQuotes = false;

   
$complete = false;
   
$search_chars_list = array('\r\n', '\n', '\r');
    if (
$delim && ($delim != ''))
       
$search_chars_list[] = $delim;
    if (
$enclosure && ($enclosure != '')) {
       
$search_chars_list[] = $enclosure;
       
$enclosure_len = strlen($enclosure);
    } else
       
$enclosure_len = 0;

    if (
$escape && ($escape != '')) {
       
$search_chars_list[] = $escape;
       
$escape_len = strlen($escape);
    } else
       
$escape_len = 0;
   
$search_regex = '/' . implode('|', $search_chars_list) . '/';

   
$cur_pos = 0;
   
$line = '';
   
$cur_value = '';
   
$in_value = false;
   
$last_value = 0;
    while (!
$complete) {
       
$read_result = fread($file_handle, BUFFER_READ_LEN);
        if (
$read_result) {
           
$line .= $read_result;
        } else if (
strlen($line) == 0) {
            return
null;
        } else {
           
$line .= "\n";
        }

       
$line_len = strlen($line);

        while (
true) {
            if (!
preg_match($search_regex, $line, $matches, PREG_OFFSET_CAPTURE, $cur_pos)) {
                if (
$read_result) {
                   
// need more chars
                   
break;
                } else {
                   
// Incomplete file
                   
return null;
                }
            } else {
               
$non_escape = false;
               
$cur_char = $matches[0][0];
               
$cur_len = strlen($cur_char);
               
$new_pos = $matches[0][1];
                if ((
$enclosure == $escape) && $in_value && ($cur_char == $escape)) {
                   
// Escape char = enclosure char special handling
                   
if (($new_pos + $cur_len + $enclosure_len) >= $line_len) {
                       
// We need the next char
                       
break;
                    }

                   
$next_char = substr($line, $new_pos + $cur_len, $enclosure_len);
                    if ((!
$enclosure) || ($next_char != $enclosure)) {
                       
$non_escape = true;
                    }
                }

               
$cur_pos = $new_pos;
                if (
$in_value && (! $non_escape)) {
                   
$cur_value .= mb_substr($line, $last_value, $cur_pos - $last_value);
                    if (
$cur_char == $escape) {
                       
// Skip escape char
                       
$cur_pos += $escape_len;
                    }
                   
$last_value = $cur_pos;
                } else if ((
$cur_char == "\n") || ($cur_char == "\r") || ($cur_char == "\r\n")) {
                   
$blank_start_lines = ($cur_pos == 0);
                    ++
$cur_pos;
                   
$cur_pos = $cur_pos + strspn($line, "\n\r", $cur_pos);
                    if (!
$blank_start_lines) {
                       
$complete = true;
                    } else {
                       
$last_value = $cur_pos;
                        continue;
                    }
                }
                if (
$cur_char == $delim || $complete) {
                    if (
is_null($fields)) {
                       
$fields = array();
                    }
                   
$fields[] = $cur_value . trim(mb_substr($line, $last_value, $cur_pos - $last_value));
                   
$last_value = $cur_pos + $cur_len;
                   
$cur_value = '';
                } else if (
$cur_char == $enclosure) {
                    if (
$in_value) {
                       
$cur_value .= mb_substr($line, $last_value, $cur_pos - $last_value);
                    }
                   
$last_value = $cur_pos + $cur_len;
                   
$in_value = ! $in_value;
                }
                if (
$complete) {
                    break;
                }
               
$cur_pos += $cur_len;
            }
        }
    }

   
fseek($file_handle, $cur_pos - strlen($line), SEEK_CUR);
    return
$fields;
}
?>
ohira atto web dotto de
08-Nov-2007 10:59
Yet another tool to parse CSV data into a associated 2d array. However, when within quotes, newline characters are treated as data instead of syntax.

<?php

define
('LF', "\n");

// Parse a CSV data to a associated 2D array
function csvToArray($data)
{
   
// output
   
$csv = array();
   
$line = array();
   
$fieldnames = array();
   
$got_fieldnames = false;
   
$escaped = false; // Flag: escape char
   
$quoted = false; // Flag: quoted string
   
$buffer = ''; // Buffer (quoted values)
   
$junk = ''; // Junk buffer (unquoted values)
   
$fieldname_index = 0;
    for(
$i = 0; $i < strlen($data); $i++)
    {
       
$char = $data[$i];

        if(
$quoted)
        {
            if((
$char == '\\') && ($escaped === false))
            {
               
// Set flags
               
$escaped = true;
            }
            elseif((
$char == '"') && ($escaped === false))
            {
               
// Set flags
               
$quoted = false;
               
$escaped = false;
            }
            else
            {
               
// Add char to buffer
               
$buffer .= $char;

               
// Set flags
               
$escaped = false;
            }
        }
        else
        {
            if(
$char == LF) // Start a new line
           
{
                if(
strlen($buffer) > 0)
                {
                   
// Add buffer to line
                   
if($got_fieldnames)
                    {
                       
$line[$fieldnames[$fieldname_index]] = $buffer;
                       
$fieldname_index++;
                    }
                    else
                    {
                       
$fieldnames[] = $buffer;
                    }
                   
// Clear buffer
                   
$buffer = '';
                }
                else
                {
                   
$junk = trim($junk);

                   
// Add junk to line (possible unquoted values?)
                   
if($got_fieldnames)
                    {
                       
$line[$fieldnames[$fieldname_index]] = $junk;
                       
$fieldname_index++;
                    }
                    else
                    {
                       
$fieldnames[] = $junk;
                    }
                }

               
// Clear junk
               
$junk = '';

               
// Add line to CSV
               
if($got_fieldnames)
                {
                   
$csv[] = $line;
                }
               
$got_fieldnames = true;
               
// Clear line
               
$line = array();
               
$fieldname_index = 0;
            }
            elseif(
$char == '"') // Start new value
           
{