May 18, 2006

PHP CSV to Array functions

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 10:58 am

Documented on PHP.net is the function fgetcsv. I have found that often it won’t do exactly what you want it to do. Thankfully there is many snippets that make it easy for us to turn a CSV file into a 2D array (array[row][column]).

On the PHP.net comments section for fgetcsv, Cristian Zuddas posts a windows based (\r\n line ending) delimeter (semi-colon or comma etc) CSV to Array function that has sparked off many variations.

/**
* Function CSV2Array
* Convert CSV-text to 2d-array
* (delimeter = ';', line ending = 'rn' - only for windows platform)
*
* Reference File: http://php.mirrors.ilisys.com.au/manual/en/function.fgetcsv.php
* @author Cristian Zuddas
* @return array
*/
function CSV2Array($content, $delim = ';', $encl = '"', $optional = 1) {
   if ($content[strlen($content)-1]!="r" && $content[strlen($content)-1]!="n")
       $content .= "rn";

   $reg = '/(('.$encl.')'.($optional?'?(?(2)':'(').
           '[^'.$encl.']*'.$encl.'|[^'.$delim.'rn]*))('.$delim.
           '|rn)/smi';

   preg_match_all($reg, $content, $treffer);
   $linecount = 0;

   for ($i = 0; $i<=count($treffer[3]);$i++) {
       $liste[$linecount][] = $treffer[1][$i];
       if ($treffer[3][$i] != $delim)
           $linecount++;
   }
   unset($linecount);
   unset($i);
   unset($reg);
   unset($content);
   unset($delim);
   unset($encl);
   unset($optional);
   unset($treffer);

   return $liste;
}

Note: I have found it is easy to place these utility functions in a Utility static class such as CSVTools. You can therefore invoke using CSVTools::CSV2Array();
You may find this working out of the box, simply read the complete contents of your file into a variable, using file_get_contents and then invoke the function above with the variable contents. It will return an array and you are on your way.

$dataRows = CSV2Array($fileContents, ',');

You can now loop through the contents using a simple foreach loop as below:

foreach($dataRows as $rowNum => $rowData) { ... }

Remember, you may have problems with this if the line endings are not Windows or MS-DOS based. Typically on a PC you have no worries when you export from Excel, but on Mac you will have the options to choose the line endings. It would be very easy to edit this to your needs, but is a good starting point.

Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • Furl
  • Reddit
  • YahooMyWeb

3 Comments »

  1. Thanks Cam just what I was looking for.

    Here’s another handy function using fgetcsv() which returns an associative array - Thanks to Donovan Bray on php.net:

    /**
    * Based on an example by ramdac at ramdac dot org
    * Returns a multi-dimensional array from a CSV file optionally using the
    * first row as a header to create the underlying data as associative arrays.
    * @param string $file Filepath including filename
    * @param bool $head Use first row as header.
    * @param string $delim Specify a delimiter other than a comma.
    * @param int $len Line length to be passed to fgetcsv
    * @return array or false on failure to retrieve any rows.
    */
    function importcsv($file,$head=false,$delim=",",$len=1000) {
    $return = false;
    $handle = fopen($file, "r");
    if ($head) {
    $header = fgetcsv($handle, $len, $delim);
    }
    while (($data = fgetcsv($handle, $len, $delim)) !== FALSE) {
    if ($head AND isset($header)) {
    foreach ($header as $key=>$heading) {
    $row[$heading]=(isset($data[$key])) ? $data[$key] : '';
    }
    $return[]=$row;
    } else {
    $return[]=$data;
    }
    }
    fclose($handle);
    return $return;
    }

    Comment by Richard Lee — May 18, 2006 @ 3:12 pm

  2. If you are having troubles using fgetcsv with MAC/Windows/Unix file endings, you can set the INI variable to auto detect.

    eg:

    auto_detect_line_endings “0″ PHP_INI_ALL Available since PHP 4.3.0.

    therefore:

    ini_set('auto_detect_line_endings','1'); // Will fix detection of line endings automatically
    

    Comment by Cameron Manderson — December 18, 2006 @ 12:42 pm

  3. […] Also found this which looks interesting: php-csv-to-array-functions […]

    Pingback by PBooks Open Source Accounting » Blog Archive » PBooks Export and Import — July 27, 2007 @ 8:58 am

RSS feed for comments on this post. TrackBack URI

Leave a comment