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, 16 May 2008

view this page in

fgetcsv

(PHP 4, PHP 5)

fgetcsv — Читает строку из файла и производит разбор данных CSV

Описание

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

handle
Корректный файловый указатель на файл, успешно открытый при помощи fopen(), popen(), или fsockopen().
length (Необязательный)
Должен быть больше самой длинной строки (в символах), найденной в CSV-файле (включая завершающий символ конца строки). Он стал необязательным в PHP 5. Если этот аргумент не указан (или равен 0 в версиях PHP 5.0.4 и выше), максимальная длинна строки не ограничена, но функция работает немного медленнее.
delimiter (Необязательный)
Устанавливает разделитель поля (только один символ). По умолчанию это запятая.
enclosure (Необязательный)
Устанавливает символ ограничителя поля (только один символ). По умолчанию это двойная кавычка. Добавлен в PHP 4.3.0.

Данная функция похожа на функцию fgets(), с той разницей, что она производит анализ строки на наличие записей в формате CSV и возвращает найденные поля в качестве массива.

Функция fgetcsv() возвращает FALSE в случае ошибки, а также по достижению конца файла.

Замечание: Пустая строка CSV-файла будет возвращена в качестве массива, содержащего единственный элемент null, ошибки в данном случае не возникнет.

Пример #1 Чтение и вывод на экран содержания CSV-файла

<?php
$row 
1;
$handle fopen("test.csv""r");
while ((
$data fgetcsv($handle1000",")) !== FALSE) {
    
$num count($data);
    echo 
"<p> $num полей в строке $row: <br /></p>\n";
    
$row++;
    for (
$c=0$c $num$c++) {
        echo 
$data[$c] . "<br />\n";
    }
}
fclose($handle);
?>

fgetcsv() стала правильно обрабатывать двоичные данные начиная с версии PHP 4.3.5

Замечание: Эта функция принимает во внимание настройки локали. К примеру, если LANG установлен в en_US.UTF-8, то файлы в однобайтовой кодировке будут неправильно прочитаны этой функцией.

Замечание: Если у вас возникают проблемы с распознаванием PHP окончания строк при чтении файлов на Macintosh-совместимом компьютере или при чтении файлов, созданных на Macintosh-совместимом компьютере, необходимо включить опцию auto_detect_line_endings.

См.также описание функций explode(), file(), pack() и fputcsv().



fgets> <fgetc
Last updated: Fri, 16 May 2008
 
add a note add a note User Contributed Notes
fgetcsv
skirkendall at NOSPAM dot dsl-only dot net
30-Apr-2008 06: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 11: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 01: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
           
{
               
// Set flags
               
$quoted = true;
            }
            elseif(
$char == ';')
            {
                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 = '';
            }
            else
// Add to junk char
           
{
               
$junk .= $char;
            }
        }
    }

    return
$csv;
}

?>
Tim Henderson
04-Oct-2007 06:40
Only problem with fgetcsv(), at least in PHP 4.x -- any stray slash in the data that happens to come before a double-quote delimiter will break it -- ie, cause the field delimiter to be escaped. I can't find a direct way to deal with it, since fgetcsv() doesn't give you a chance to manipulate the line before it reads it and parses it...I've had to change all occurrences of '\"' to '" in the file first before feeding ot to fgetcsv(). Otherwise this is perfect for that Microsoft-CSV formula, deals gracefully with all the issues.
marcus at synchromedia dot co dot uk
03-Oct-2007 09:44
This is a minor fix to mortanon@gmail.com's CSVIterator. The original version would die if the last line of a file did not end in a line break and you called valid() inside the iterator loop because the file would have already been closed and thus feof() would have an invalid file pointer param.

<?php
/**
* @author mortanon@gmail.com
* @link http://uk.php.net/manual/en/function.fgetcsv.php
*/
class CsvIterator implements Iterator {
    const
ROW_SIZE = 4096;
   
/**
    * The pointer to the cvs file.
    * @var resource
    * @access private
    */
   
private $filePointer = NULL;
   
/**
    * The current element, which will
    * be returned on each iteration.
    * @var array
    * @access private
    */
   
private $currentElement = NULL;
   
/**
    * The row counter.
    * @var int
    * @access private
    */
   
private $rowCounter = NULL;
   
/**
    * The delimiter for the csv file.
    * @var str
    * @access private
    */
   
private $delimiter = NULL;

   
/**
    * This is the constructor.It try to open the csv file.The method throws an exception
    * on failure.
    *
    * @access public
    * @param str $file The csv file.
    * @param str $delimiter The delimiter.
    *
    * @throws Exception
    */
   
public function __construct($file, $delimiter=',') {
        try {
           
$this->filePointer = fopen($file, 'r');
           
$this->delimiter = $delimiter;
        }
        catch (
Exception $e) {
            throw new
Exception('The file "'.$file.'" cannot be read.');
        }
    }

   
/**
    * This method resets the file pointer.
    *
    * @access public
    */
   
public function rewind() {
       
$this->rowCounter = 0;
       
rewind($this->filePointer);
    }

   
/**
    * This method returns the current csv row as a 2 dimensional array
    *
    * @access public
    * @return array The current csv row as a 2 dimensional array
    */
   
public function current() {
       
$this->currentElement = fgetcsv($this->filePointer, self::ROW_SIZE, $this->delimiter);
       
$this->rowCounter++;
        return
$this->currentElement;
    }
   
   
/**
    * This method returns the current row number.
    *
    * @access public
    * @return int The current row number
    */
   
public function key() {
        return
$this->rowCounter;
    }
   
   
/**
    * This method checks if the end of file is reached.
    *
    * @access public
    * @return boolean Returns true on EOF reached, false otherwise.
    */
   
public function next() {
        if (
is_resource($this->filePointer)) {
            return !
feof($this->filePointer);
        }
        return
false;
    }
   
   
/**
    * This method checks if the next row is a valid row.
    *
    * @access public
    * @return boolean If the next row is a valid row.
    */
   
public function valid() {
        if (!
$this->next()) {
            if (
is_resource($this->filePointer)) {
               
fclose($this->filePointer);
            }
            return
false;
        }
        return
true;
    }
}
?>
daevid at daevid dot com
26-Sep-2007 12:39
A much simpler way to map the heading/column names to the elements on each line. It also doesn't fill up one big array which could cause you to run out of memory on large datasets. This loads one at a time so you can process/insert to db/etc...

$handle = fopen('somefile.csv', 'r');
if ($handle)
{
    set_time_limit(0);
   
    //the top line is the field names
    $fields = fgetcsv($handle, 4096, ',');
   
    //loop through one row at a time
    while (($data = fgetcsv($handle, 4096, ',')) !== FALSE)
    {
        $data = array_combine($fields, $data);
    }

    fclose($handle);
}
jszatmary at hotmail dot com
21-Aug-2007 07:06
This function appears to assume that \" is an escaped quote - similar to "" - which may lead to incorrect results while reading some files. Found while running under PHP 5.1.6.
myrddin at myrddin dot myrddin
21-Jun-2007 01:16
RE post by:-  stinkyj at gmail dot com
02-Aug-2006 10:15
the enclosure param defaulting to " and giving a warning if it's an empty string makes this function nearly worthless. csv files do not always have the fields enclosed, and in those cases it doesn't work.
---------
I had the same problem with this as well, enclosure really should be possible to be made null.

However, perhaps a solution to the problem is to use "\n" as the enclosure character in fgetcsv. As far as I tested it seems to work out just fine. I was thinking of using "\0" but that may cause problems with some data files. If anyone knows of any issues that might crop up when using "\n" as enclosure, please post away. Thanks.
e at osterman dot com
13-Jun-2007 02:39
A 5.2 way to lazily parse a single CSV line

function parseCSV($str, $delimiter = ',', $enclosure = '"', $len = 4096)
{
  $fh = fopen('php://memory', 'rw');
  fwrite($fh, $str);
  rewind($fh);
  $result = fgetcsv( $fh, $len, $delimiter, $enclosure );
  fclose($fh);
  return $result;
}
D Steer
11-Jun-2007 07:32
Here is a simple to include the field names in the array. Altough this is very simple, it does the job fantastically

<?php

print_r
(buildStock('stock.csv'));

function
buildStock($File) {
       
$handle = fopen($File, "r");
       
$fields = fgetcsv($handle, 1000, ",");
       
        while(
$data = fgetcsv($handle, 1000, ",")) {
           
$detail[] = $data;
        }
       
       
$x = 0;
       
$y = 0;
           
        foreach(
$detail as $i) {
            foreach(
$fields as $z) {
               
$stock[$x][$z] = $i[$y];
               
$y++;
            }
           
$y = 0;
           
$x++;
        }
        return
$stock;
    }
?>
anykey
24-May-2007 01:40
final version...

<?php
   
private function parseCsvLine($str) {
       
$delimier = ';';
       
$qualifier = '"';
       
$qualifierEscape = '\\';

       
$fields = array();
        while (
strlen($str) > 0) {
            if (
$str{0} == $delimier)
               
$str = substr($str, 1);
            if (
$str{0} == $qualifier) {
               
$value = '';
                for (
$i = 1; $i < strlen($str); $i++) {
                    if ((
$str{$i} == $qualifier) && ($str{$i-1} != $qualifierEscape)) {
                       
$str = substr($str, (strlen($value) + 2));
                       
$value = str_replace(($qualifierEscape.$qualifier), $qualifier, $value);
                        break;
                    }
                   
$value .= $str{$i};
                }
            } else {
               
$end = strpos($str, $delimier);
               
$value = ($end !== false) ? substr($str, 0, $end) : $str;
               
$str = substr($str, strlen($value));
            }
           
$fields[] = $value;
        }
        return
$fields;
    }

?>
01-May-2007 02:07
a flexible parser that can be used for csv or tsv (or any delimited flatfile data source).

<?php

/* assumes a single line of input; automatically determines the number of fields */
function parse_line($input_text, $delimiter = ',', $text_qualifier = '"') {
   
$text = trim($input_text);
   
    if(
is_string($delimiter) && is_string($text_qualifier)) {
       
$re_d = '\x' . dechex(ord($delimiter));            //format for regexp
       
$re_tq = '\x' . dechex(ord($text_qualifier));    //format for regexp
   
       
$fields = array();
       
$field_num = 0;
        while(
strlen($text) > 0) {
            if(
$text{0} == $text_qualifier) {
               
preg_match('/^' . $re_tq . '((?:[^' . $re_tq . ']|(?<=\x5c)' . $re_tq . ')*)' . $re_tq . $re_d . '?(.*)$/', $text, $matches);
               
               
$value = str_replace('\\' . $text_qualifier, $text_qualifier, $matches[1]);
               
$text = trim($matches[2]);
               
               
$fields[$field_num++] = $value;
            } else {
               
preg_match('/^([^' . $re_d . ']*)' . $re_d . '?(.*)$/', $text, $matches);
               
               
$value = $matches[1];
               
$text = trim($matches[2]);
               
               
$fields[$field_num++] = $value;
            }
        }
   
        return
$fields;
    } else {
        return
false;
    }
}

?>
Bob
29-Apr-2007 04:19
Thank you to the mystery contributor of csv_string_to_array function:

http://uk3.php.net/manual/en/function.fgetcsv.php#62524

This works great when your CSV data has literal commas inside enclosures that you want to preserve, fgetcsv fails at this & interprets comma as end of item even without ending enclosure.
r at smagoo dot ch
11-Apr-2007 07:00
If you had a problem with fgetcsv and multibyte characters, you have to set the correct local setting:

<?php
setlocale
(LC_ALL, 'en_US.UTF-8');
?>

Change it to your local settings and/or charset.
pinkgothic at gmail dot com
03-Apr-2007 06:47
I find the documentation mildly misleading:

fgetcsv() does not - as this documentation seemingly claims in the descriptive line - get a line out of the file (via the file pointer) and then parses this for CSV fields, but instead retrieves a CSV row out of the file, which it then splits into an array.

The difference may seem trivial, but reading the description of this function I feared it might not support linebreaks in individual CSV values. Testing, however, revealed that fgetcsv() [fortunately!] works as one would expect from a CSV parser, and my fears were without cause.

In fact, fgetcsv() is remarkably hard to break. It's not confused by the value """,""" for example (three quotation marks followed by a comma followed by three quotation marks - which represents the value "quotation mark, comma, quotation mark" in case it's not immediately obvious).

I hope this extra documentation is helpful for someone.
eoj at seznam dot cz
13-Mar-2007 01:09
I had a problem with fgetcsv and multibyte characters so i used one of functions below (16-Nov-2002 04:01 to be specific) and modified it to be (hopefully) multibyte safe.

<?php
/**
 * @param the csv line to be split
 * @param the delimiter to split by (default ';' )
 * @param if this is false, the quotation marks won't be removed from the fields (default true)
 */
function mb_csv_split($line, $delim = ';', $removeQuotes = true) {
   
$fields = array();
   
$fldCount = 0;
   
$inQuotes = false;

    for (
$i = 0; $i < mb_strlen($line); $i++) {
        if (!isset(
$fields[$fldCount])) $fields[$fldCount] = "";
       
$tmp = mb_substr($line, $i, mb_strlen($delim));
        if (
$tmp === $delim && !$inQuotes) {
           
$fldCount++;
           
$i+= mb_strlen($delim) - 1;
        }
        else if (
$fields[$fldCount] == "" && mb_substr($line, $i, 1) == '"' && !$inQuotes) {
            if (!
$removeQuotes) $fields[$fldCount] .= mb_substr($line, $i, 1);
           
$inQuotes = true;
        }
        else if (
mb_substr($line, $i, 1) == '"') {
            if (
mb_substr($line, $i+1, 1) == '"') {
               
$i++;
               
$fields[$fldCount] .= mb_substr($line, $i, 1);
            } else {
                if (!
$removeQuotes) $fields[$fldCount] .= mb_substr($line, $i, 1);
               
$inQuotes = false;
            }
        }
        else {
           
$fields[$fldCount] .= mb_substr($line, $i, 1);
        }
    }
    return
$fields;
}
?>
31-Jan-2007 08:23
just another csv file parse function

<?php

define
('CSV_BOTH', 1);
define('CSV_ASSOC', 2);
define('CSV_NUM', 3);

function
parse_csv($filename, $result_type = CSV_BOTH) {
    if(!
file_exists($filename)) {
        die(
"file (" . $filename . ") does not exist\n");
    }
   
   
$lines = file($filename);
   
   
$title_line = trim(array_shift($lines));
   
$titles = split(",", $title_line);
   
   
$records = array();
    foreach(
$lines as $line_num => $line) {   
       
$subject = trim($line);
       
$fields = array();
        for(
$field_num = 0; $field_num < count($titles); $field_num++) {
            if(
$subject{0} == '"') {
               
preg_match('/^"(([^"]|\\")*)",?(.*)$/', $subject, $matches);
               
               
$value = $matches[1];
               
$subject = $matches[3];
               
                if(
$result_type == CSV_BOTH || $result_type == CSV_ASSOC) {
                   
$fields[$titles[$field_num]] = $value;
                }
               
                if(
$result_type == CSV_BOTH || $result_type == CSV_NUM) {
                   
$fields[$field_num] = $value;
                }
            } else {
               
preg_match('/^([^,]*),?(.*)$/', $subject, $matches);
               
               
$value = $matches[1];
               
$subject = $matches[2];
               
                if(
$result_type == CSV_BOTH || $result_type == CSV_ASSOC) {
                   
$fields[$titles[$field_num]] = $value;
                }
               
                if(
$result_type == CSV_BOTH || $result_type == CSV_NUM) {
                   
$fields[$field_num] = $value;
                }
            }
        }
       
       
$records[] = $fields;
    }

    return
$records;
}

?>
Mr N.
05-Jan-2007 01:23
There is still a bug with column headings ( "false" != false )
<?php
   
function parse_csv_file($file, $columnheadings = false, $delimiter = ',', $enclosure = "\"") {
 
      
$row = 1;
      
$rows = array();
      
$handle = fopen($file, 'r');
 
       while ((
$data = fgetcsv($handle, 1000, $delimiter, $enclosure )) !== FALSE) {
 
           if (!(
$columnheadings == false) && ($row == 1)) {
              
$headingTexts = $data;
           } elseif (!(
$columnheadings == false)) {
               foreach (
$data as $key => $value) {
                   unset(
$data[$key]);
                  
$data[$headingTexts[$key]] = $value;
               }
              
$rows[] = $data;
           } else {
              
$rows[] = $data;
           }
          
$row++;
       }
 
      
fclose($handle);
       return
$rows;
    }
?>
lj at matter dot dk
06-Nov-2006 06:15
There was a bug with the column headings

function parse_csv_file($file, $columnheadings = false, $delimiter = ',', $enclosure = "\"") {
       
        $row = 1;
        $rows = array();
        $handle = fopen($file, 'r');
       
        while (($data = fgetcsv($handle, 1000, $delimiter, $enclosure )) !== FALSE) {
       
            if (!($columnheadings == "false") && ($row == 1)) {
                $headingTexts = $data;
            } elseif (!($columnheadings == "false")) {
                foreach ($data as $key => $value) {
                    unset($data[$key]);
                    $data[$headingTexts[$key]] = $value;
                }
                $rows[] = $data;
            } else {
                $rows[] = $data;
            }
            $row++;
        }
       
        fclose($handle);
        return $rows;
    }
aruggirello, at, tiscali, d0t it
10-Oct-2006 09:20
Whenever you have to parse CSV data that isn't stored in a file, or should you need to encode your data as CSV, you may use my set of functions, featuring:

- bi-directional conversion, meaning you may read as well as write CSV data, to or from your arrays.
- Support for customizable field separator, newline character (also auto-detects and converts Win/Mac/*nix newlines).
- separators, newlines (auto-converted), properly handled within fields enclosed in quotation marks. Last line may or may not be terminated by a newline.
- checks for possibly corrupt data (whenever last field in last row starts, but is not terminated, with a quotation mark).
- Top speed guaranteed by use of strpos(), substr() etc.; room yet for some optimization (especially with associative arrays).
- Clean (no data stored or retrieved from outside function scope, except for CSVstruct array).

Requires PHP 4.3 or newer.
Enjoy!
Andrea Ruggirello

souce available at:
http://web.tiscali.it/caelisoft/provacsv.txt
spam at cyber-space dot nl
07-Sep-2006 06:23
I needed a fast/robust csv parser in PHP that could handle unix-, windows- and mac-style linebreaks.

i takes a csv-string as input and outputs a multidimensional array with lines and fields.

<?php
function parse_csv_php(&$data,$delim=',',$enclosure='"')
{
 
$enclosed=false;
 
$fldcount=0;
 
$linecount=0;
 
$fldval='';
 for(
$i=0;$i<strlen($data);$i++)
 {
 
$chr=$data{$i};
  switch(
$chr)
  {
   case
$enclosure:
    if(
$enclosed&&$data{$i+1}==$enclosure)
    {
    
$fldval.=$chr;
     ++
$i; //skip next char
   
}
    else
    
$enclosed=!$enclosed;
    break;
   case
$delim:
    if(!
$enclosed)
    {
    
$ret_array[$linecount][$fldcount++]=$fldval;
    
$fldval='';
    }
    else
    
$fldval.=$chr;
    break;
   case
"\\r":
    if(!
$enclosed&&$data{$i+1}=="\\n")
     continue;
   case
"\\n":
    if(!
$enclosed)
    {
    
$ret_array[$linecount++][$fldcount]=$fldval;
    
$fldcount=0;
    
$fldval='';
    }
    else
    
$fldval.=$chr;
    break;
   default:
   
$fldval.=$chr;
  }
 }
 if(
$fldval)
 
$ret_array[$linecount][$fldcount]=$fldval;
 return
$ret_array;
}
?>
Skakunov Alexander <i1t2b3 at gmail dot com>
24-Aug-2006 03:42
If you need to import a huge CSV file into a database, use the bulk insert technique instead of many line-by-line inserts:
- MSSQL: bcp tool and "BULK INSERT" SQL
- MySQL: mysqlimport tool and "LOAD DATA INFILE" SQL

As for MySQL, you can use the ready "Quick CSV import" class at http://a4.users.phpclasses.org/browse/package/2917.html
stinkyj at gmail dot com
02-Aug-2006 07:15