Return to Snippet

Revision: 30561
at August 17, 2010 14:31 by Sverri


Initial Code
/*
  Simple CSV Reader
  
  So, a few ground rules:
  - Rows must end with a newline
  - Rows cannot have newlines in them
  - All values must be enclosed in double quotes.
  - Double quotes are allowed inside values.
  
  If the file is not formatted according to these rules then
  the world as we know it will cease to exist.
  
  Available public methods:
  - log(): Returns an array log if something is out of order.
  
  Have a good day.
*/

class CSVreader
{
  private $log;
  
  public function __construct($filename = NULL)
  {
    if ($filename)
    {
      $this->open($filename);
    }
  }
  
  private function open($filename)
  {
    if ( ! file_exists($filename)) die ("File $filename does not exist.");
    
    if ( ! is_readable($filename)) die ("File $filename is not readable.");
    
    $lines = file($filename, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
    
    $fields = $this->line_values( array_shift($lines) );
    
    $fieldCount = count($fields);
    
    foreach($lines as $key => $values)
    {
      $values = $this->line_values($values);
      
      $valueCount = count($values);
      
      $line = $key + 2;
      
      if ($valueCount < $fieldCount)
      {
        $missing = $fieldCount - $valueCount;
        
        for ($x=0; $x<$missing; $x++) $values[] = '(n/a)';
        
        $this->log_message($line, "$missing ".($missing==1?'value is':'values are')." missing");
      }
      if ($valueCount > $fieldCount)
      {
        $tooMany = $valueCount - $fieldCount;
        
        $this->log_message($line, "There ".($tooMany==1?"is 1 value":"are $tooMany values")." too many");
      }
      $i = 0;
      
      foreach ($values as $val)
      {
        if (empty($val))
        {
          $this->log_message($line, "There is an empty value");
        }
        $fieldName = $fields[$i];
        
        if ( ! $fieldName) continue;
        
        $this->{$line}->$fields[$i] = $val;
        
        $i++;
      }
    }
  }
  
  public function log()
  {
    return $this->log;
  }
  
  private function line_values(&$line)
  {
    $line = trim($line);
    
    $values = preg_split('/"([ \t]+)?,([ \t]+)?"/', $line);
    
    foreach ($values as &$val)
    {
      $val = trim($val, '"');
    }
    return $values;
  }
  
  private function log_message($line, $message)
  {
    $this->log[] = "Line $line: $message";
  }
  
}

/*
Example.txt:
"firstname","surname"
"Jane","Doe"
"John","Doe"
*/

$csv = new CSVreader('Example.txt');
foreach ($csv as $line => $row) {
  echo "$line: {$row->firstname} {$row->surname}<br />\n";
}

Initial URL

                                

Initial Description
See code comments for more details.

Initial Title
Simple CSV Reader

Initial Tags
csv

Initial Language
PHP