<?php
 
 
/**
 
 * This class will parse a csv file in either standard or MS Excel format.
 
 * Two methods are provided to either process a line at a time or return the whole csv file as an array.
 
 *
 
 * It can deal with:
 
 * - Line breaks within quoted fields
 
 * - Character seperator (usually a comma or semicolon) in quoted fields
 
 * - Can leave or remove leading and trailing \s or \t
 
 * - Can leave or skip empty rows.
 
 * - Windows and Unix line breaks dealt with automatically. Care must be taken with Macintosh format.
 
 *
 
 * Also, the escape character is automatically removed.
 
 *
 
 * NOTICE:
 
 * - Quote character can be escaped by itself or by using an escape character, within a quoted field (i.e. "" or \" will work)
 
 *
 
 * USAGE:
 
 *
 
 * include_once 'class.csv_bv.php';
 
 *
 
 * $csv = & new csv_bv('test.csv', ';', '"' , '\\');
 
 * $csv->SkipEmptyRows(TRUE); // Will skip empty rows. TRUE by default. (Shown here for example only).
 
 * $csv->TrimFields(TRUE); // Remove leading and trailing \s and \t. TRUE by default.
 
 *
 
 * while ($arr_data = $csv->NextLine()){
 
 * 
 
 *         echo "<br><br>Processing line ". $csv->RowCount() . "<br>";
 
 *         echo implode(' , ', $arr_data);
 
 *
 
 * }
 
 *
 
 * echo "<br><br>Number of returned rows: ".$csv->RowCount();
 
 * echo "<br><br>Number of skipped rows: ".$csv->SkippedRowCount();
 
 *
 
 * ----
 
 * OR using the csv2array function.
 
 * ----
 
 *
 
 * include_once 'class.csv_bv.php';
 
 *
 
 * $csv = & new csv_bv('test.csv', ';', '"' , '\\');
 
 * $csv->SkipEmptyRows(TRUE); // Will skip empty rows. TRUE by default. (Shown here for example only).
 
 * $csv->TrimFields(TRUE); // Remove leading and trailing \s and \t. TRUE by default.
 
 *
 
 * $_arr = $csv->csv2Array();
 
 * print_r($_arr);
 
 *
 
 * echo "<br><br>Number of returned rows: ".$csv->RowCount();
 
 * echo "<br><br>Number of skipped rows: ".$csv->SkippedRowCount();
 
 *
 
 *
 
 * WARNING:
 
 * - Macintosh line breaks need to be dealt with carefully. See the PHP help files for the function 'fgetcsv'
 
 * 
 
 * The coding standards used in this file can be found here: http://www.dagbladet.no/development/phpcodingstandard/
 
 *
 
 *    All commets and suggestions are welcomed.
 
 *
 
 * SUPPORT: Visit http://vhd.com.au/forum/
 
 *
 
 * CHANGELOG: 
 
 * 
 
 * - Fixed skipping of last row if the last row did not have a new line. Thanks to Florian Bruch and Henry Flurry. (2006_05_15)
 
 * - Changed the class name to csv_bv for consistency. (2006_05_15)
 
 * - Fixed small problem where line breaks at the end of file returned a warning (2005_10_28) 
 
 * 
 
 * @author Ben Vautier <[email protected]> 
 
 * @copyright (c) 2006
 
 * @license BSD
 
 * @version 1.2 (2006_05_15) 
 
 */
 
 
 
class csv_bv
 
{
 
    /**
 
      * Seperator character
 
      * @var char
 
      * @access private
 
      */
 
    var $mFldSeperator;
 
    
 
    /**
 
      * Enclose character
 
      * @var char
 
      * @access private
 
      */
 
    var $mFldEnclosure;
 
    
 
    /**
 
      * Escape character
 
      * @var char
 
      * @access private
 
      */
 
    var $mFldEscapor;
 
    
 
    /**
 
      * Length of the largest row in bytes.Default is 4096
 
      * @var int
 
      * @access private
 
      */
 
    var $mRowSize;
 
    
 
    /**
 
      * Holds the file pointer
 
      * @var resource
 
      * @access private
 
      */
 
    var $mHandle;
 
    
 
    /**
 
      * Counts the number of rows that have been returned
 
      * @var int
 
      * @access private
 
      */
 
    var $mRowCount;
 
    
 
    /**
 
      * Counts the number of empty rows that have been skipped
 
      * @var int
 
      * @access private
 
      */
 
    var $mSkippedRowCount;
 
    
 
    /**
 
      * Determines whether empty rows should be skipped or not.
 
      * By default empty rows are returned.
 
      * @var boolean
 
      * @access private
 
      */
 
    var $mSkipEmptyRows;
 
    
 
    /**
 
      * Specifies whether the fields leading and trailing \s and \t should be removed
 
      * By default it is TRUE.
 
      * @var boolean
 
      * @access private
 
      */
 
    var $mTrimFields;
 
    
 
    /**
 
      * Constructor
 
      *
 
      * Only used to initialise variables.
 
      *
 
      * @param str $file - file path
 
      * @param str $seperator - Only one character is allowed (optional) 
 
      * @param str $enclose - Only one character is allowed (optional) 
 
      * @param str $escape - Only one character is allowed (optional) 
 
      * @access public
 
      */
 
    Function csv_bv($file, $seperator = ',', $enclose = '"', $escape = ''){
 
        
 
        $this->mFldSeperator = $seperator;
 
        $this->mFldEnclosure = $enclose;
 
        $this->mFldEscapor = $escape;
 
        
 
        $this->mSkipEmptyRows = TRUE;
 
        $this->mTrimFields =  TRUE;
 
        
 
        $this->mRowCount = 0;
 
        $this->mSkippedRowCount = 0;
 
        
 
        $this->mRowSize = 4096;
 
        
 
        // Open file 
 
        $this->mHandle = @fopen($file, "r") or trigger_error('Unable to open csv file', E_USER_ERROR);
 
    }
 
    
 
    
 
    /**
 
      * csv::NextLine() returns an array of fields from the next csv line.
 
      *
 
      * The position of the file pointer is stored in PHP internals.
 
      *
 
      * Empty rows can be skipped
 
      * Leading and trailing \s and \t can be removed from each field
 
      *
 
      * @access public
 
      * @return array of fields
 
      */
 
    Function NextLine(){
 
        
 
        if (feof($this->mHandle)){
 
            return False;
 
        }
 
        
 
        $arr_row = fgetcsv ($this->mHandle, $this->mRowSize, $this->mFldSeperator, $this->mFldEnclosure);
 
        
 
        $this->mRowCount++;
 
        
 
        //-------------------------
 
        // Skip empty rows if asked to
 
        if ($this->mSkipEmptyRows){
 
            
 
            
 
            if ($arr_row[0] === ''  && count($arr_row) === 1){
 
                
 
                $this->mRowCount--;
 
                $this->mSkippedRowCount++;
 
                
 
                $arr_row = $this->NextLine();
 
                
 
                // This is to avoid a warning when empty lines are found at the bvery end of a file.
 
                if (!is_array($arr_row)){ // This will only happen if we are at the end of a file.
 
                    return FALSE;
 
                }
 
            }
 
        }
 
        
 
        //-------------------------
 
        // Remove leading and trailing spaces \s and \t
 
        if ($this->mTrimFields && is_array($arr_row)){
 
            array_walk($arr_row, array($this, 'ArrayTrim'));
 
        }
 
        
 
        //-------------------------
 
        // Remove escape character if it is not empty and different from the enclose character
 
        // otherwise fgetcsv removes it automatically and we don't have to worry about it.
 
        if ($this->mFldEscapor !== '' && $this->mFldEscapor !== $this->mFldEnclosure && is_array($arr_row)){
 
            array_walk($arr_row, array($this, 'ArrayRemoveEscapor'));
 
        }
 
        
 
        return $arr_row;
 
    }
 
    
 
    /**
 
      * csv::Csv2Array will return the whole csv file as 2D array
 
      *
 
      * @access public
 
      */
 
    Function Csv2Array(){
 
        
 
        $arr_csv = array();
 
        
 
        while ($arr_row = $this->NextLine()){
 
            $arr_csv[] = $arr_row;
 
        }
 
        
 
        return $arr_csv;
 
    }
 
    
 
    /**
 
      * csv::ArrayTrim will remove \s and \t from an array
 
      *
 
      * It is called from array_walk.
 
      * @access private
 
      */
 
    Function ArrayTrim(&$item, $key){
 
        $item = trim($item, " \t"); // space and tab
 
    }
 
    
 
    /**
 
      * csv::ArrayRemoveEscapor will escape the enclose character
 
      *
 
      * It is called from array_walk.
 
      * @access private
 
      */
 
    Function ArrayRemoveEscapor(&$item, $key){
 
        $item = str_replace($this->mFldEscapor.$this->mFldEnclosure, $this->mFldEnclosure, $item);
 
    }
 
    
 
    /**
 
      * csv::RowCount return the current row count
 
      *
 
      * @access public
 
      * @return int
 
      */
 
    Function RowCount(){
 
        return $this->mRowCount;
 
    }
 
    
 
    /**
 
      * csv::RowCount return the current skipped row count
 
      *
 
      * @access public
 
      * @return int
 
      */
 
    Function SkippedRowCount(){
 
        return $this->mSkippedRowCount;
 
    }
 
    
 
    /**
 
      * csv::SkipEmptyRows, sets whether empty rows should be skipped or not
 
      *
 
      * @access public
 
      * @param bool $bool
 
      * @return void
 
      */
 
    Function SkipEmptyRows($bool = TRUE){
 
        $this->mSkipEmptyRows = $bool;
 
    }
 
    
 
    /**
 
      * csv::TrimFields, sets whether fields should have their \s and \t removed.
 
      *
 
      * @access public
 
      * @param bool $bool
 
      * @return void
 
      */
 
    Function TrimFields($bool = TRUE){
 
        $this->mTrimFields = $bool;
 
    }
 
    
 
}
 
 
?>
 
 
 |