Import CSV

<?php

require_once ‘parsecsv.lib.php’;

$csv = new parseCSV();

$csv->auto(‘test.csv’);

foreach ($csv->data as $key => $row)
{
$email = $row[‘Email’];


}

?>

parsecsv.lib.php

<?php

class parseCSV {

/*

Code Examples
—————-
# general usage
$csv = new parseCSV(‘data.csv’);
print_r($csv->data);
—————-
# tab delimited, and encoding conversion
$csv = new parseCSV();
$csv->encoding(‘UTF-16’, ‘UTF-8’);
$csv->delimiter = “\t”;
$csv->parse(‘data.tsv’);
print_r($csv->data);
—————-
# auto-detect delimiter character
$csv = new parseCSV();
$csv->auto(‘data.csv’);
print_r($csv->data);
—————-
# modify data in a csv file
$csv = new parseCSV();
$csv->sort_by = ‘id’;
$csv->parse(‘data.csv’);
# “4” is the value of the “id” column of the CSV row
$csv->data[4] = array(‘firstname’ => ‘John’, ‘lastname’ => ‘Doe’, ’email’ => ‘john@doe.com’);
$csv->save();
—————-
# add row/entry to end of CSV file
#  – only recommended when you know the extact sctructure of the file
$csv = new parseCSV();
$csv->save(‘data.csv’, array(‘1986’, ‘Home’, ‘Nowhere’, ”), true);
—————-
# convert 2D array to csv data and send headers
# to browser to treat output as a file and download it
$csv = new parseCSV();
$csv->output (true, ‘movies.csv’, $array);
—————-

*/

/**
* Configuration
* – set these options with $object->var_name = ‘value’;
*/

# use first line/entry as field names
var $heading = true;

# override field names
var $fields = array();

# sort entries by this field
var $sort_by = null;
var $sort_reverse = false;

# delimiter (comma) and enclosure (double quote)
var $delimiter = ‘,’;
var $enclosure = ‘”‘;

# basic SQL-like conditions for row matching
var $conditions = null;

# number of rows to ignore from beginning of data
var $offset = null;

# limits the number of returned rows to specified amount
var $limit = null;

# number of rows to analyze when attempting to auto-detect delimiter
var $auto_depth = 15;

# characters to ignore when attempting to auto-detect delimiter
var $auto_non_chars = “a-zA-Z0-9\n\r”;

# preferred delimiter characters, only used when all filtering method
# returns multiple possible delimiters (happens very rarely)
var $auto_preferred = “,;\t.:|”;

# character encoding options
var $convert_encoding = false;
var $input_encoding = ‘ISO-8859-1’;
var $output_encoding = ‘ISO-8859-1’;

# used by unparse(), save(), and output() functions
var $linefeed = “\r\n”;

# only used by output() function
var $output_delimiter = ‘,’;
var $output_filename = ‘data.csv’;

/**
* Internal variables
*/

# current file
var $file;

# loaded file contents
var $file_data;

# array of field values in data parsed
var $titles = array();

# two dimentional array of CSV data
var $data = array();

/**
* Constructor
* @param   input   CSV file or string
* @return  nothing
*/
function parseCSV ($input = null, $offset = null, $limit = null, $conditions = null) {
if ( $offset !== null ) $this->offset = $offset;
if ( $limit !== null ) $this->limit = $limit;
if ( count($conditions) > 0 ) $this->conditions = $conditions;
if ( !empty($input) ) $this->parse($input);
}

// ==============================================
// —– [ Main Functions ] ———————
// ==============================================

/**
* Parse CSV file or string
* @param   input   CSV file or string
* @return  nothing
*/
function parse ($input = null, $offset = null, $limit = null, $conditions = null) {
if ( !empty($input) ) {
if ( $offset !== null ) $this->offset = $offset;
if ( $limit !== null ) $this->limit = $limit;
if ( count($conditions) > 0 ) $this->conditions = $conditions;
if ( is_readable($input) ) {
$this->data = $this->parse_file($input);
} else {
$this->file_data = &$input;
$this->data = $this->parse_string();
}
if ( $this->data === false ) return false;
}
return true;
}

/**
* Save changes, or new file and/or data
* @param   file     file to save to
* @param   data     2D array with data
* @param   append   append current data to end of target CSV if exists
* @param   fields   field names
* @return  true or false
*/
function save ($file = null, $data = array(), $append = false, $fields = array()) {
if ( empty($file) ) $file = &$this->file;
$mode = ( $append ) ? ‘at’ : ‘wt’ ;
$is_php = ( preg_match(‘/\.php$/i’, $file) ) ? true : false ;
return $this->_wfile($file, $this->unparse($data, $fields, $append, $is_php), $mode);
}

/**
* Generate CSV based string for output
* @param   output      if true, prints headers and strings to browser
* @param   filename    filename sent to browser in headers if output is true
* @param   data        2D array with data
* @param   fields      field names
* @param   delimiter   delimiter used to separate data
* @return  CSV data using delimiter of choice, or default
*/
function output ($output = true, $filename = null, $data = array(), $fields = array(), $delimiter = null) {
if ( empty($filename) ) $filename = $this->output_filename;
if ( $delimiter === null ) $delimiter = $this->output_delimiter;
$data = $this->unparse($data, $fields, null, null, $delimiter);
if ( $output ) {
header(‘Content-type: application/csv’);
header(‘Content-Disposition: inline; filename=”‘.$filename.'”‘);
echo $data;
}
return $data;
}

/**
* Convert character encoding
* @param   input    input character encoding, uses default if left blank
* @param   output   output character encoding, uses default if left blank
* @return  nothing
*/
function encoding ($input = null, $output = null) {
$this->convert_encoding = true;
if ( $input !== null ) $this->input_encoding = $input;
if ( $output !== null ) $this->output_encoding = $output;
}

/**
* Auto-Detect Delimiter: Find delimiter by analyzing a specific number of
* rows to determine most probable delimiter character
* @param   file           local CSV file
* @param   parse          true/false parse file directly
* @param   search_depth   number of rows to analyze
* @param   preferred      preferred delimiter characters
* @param   enclosure      enclosure character, default is double quote (“).
* @return  delimiter character
*/
function auto ($file = null, $parse = true, $search_depth = null, $preferred = null, $enclosure = null) {

if ( $file === null ) $file = $this->file;
if ( empty($search_depth) ) $search_depth = $this->auto_depth;
if ( $enclosure === null ) $enclosure = $this->enclosure;

if ( $preferred === null ) $preferred = $this->auto_preferred;

if ( empty($this->file_data) ) {
if ( $this->_check_data($file) ) {
$data = &$this->file_data;
} else return false;
} else {
$data = &$this->file_data;
}

$chars = array();
$strlen = strlen($data);
$enclosed = false;
$n = 1;
$to_end = true;

// walk specific depth finding posssible delimiter characters
for ( $i=0; $i < $strlen; $i++ ) {
$ch = $data{$i};
$nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
$pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;

// open and closing quotes
if ( $ch == $enclosure && (!$enclosed || $nch != $enclosure) ) {
$enclosed = ( $enclosed ) ? false : true ;

// inline quotes
} elseif ( $ch == $enclosure && $enclosed ) {
$i++;

// end of row
} elseif ( ($ch == “\n” && $pch != “\r” || $ch == “\r”) && !$enclosed ) {
if ( $n >= $search_depth ) {
$strlen = 0;
$to_end = false;
} else {
$n++;
}

// count character
} elseif (!$enclosed) {
if ( !preg_match(‘/[‘.preg_quote($this->auto_non_chars, ‘/’).’]/i’, $ch) ) {
if ( !isset($chars[$ch][$n]) ) {
$chars[$ch][$n] = 1;
} else {
$chars[$ch][$n]++;
}
}
}
}

// filtering
$depth = ( $to_end ) ? $n-1 : $n ;
$filtered = array();
foreach( $chars as $char => $value ) {
if ( $match = $this->_check_count($char, $value, $depth, $preferred) ) {
$filtered[$match] = $char;
}
}

// capture most probable delimiter
ksort($filtered);
$delimiter = reset($filtered);
$this->delimiter = $delimiter;

// parse data
if ( $parse ) $this->data = $this->parse_string();

return $delimiter;

}

// ==============================================
// —– [ Core Functions ] ———————
// ==============================================

/**
* Read file to string and call parse_string()
* @param   file   local CSV file
* @return  2D array with CSV data, or false on failure
*/
function parse_file ($file = null) {
if ( $file === null ) $file = $this->file;
if ( empty($this->file_data) ) $this->load_data($file);
return ( !empty($this->file_data) ) ? $this->parse_string() : false ;
}

/**
* Parse CSV strings to arrays
* @param   data   CSV string
* @return  2D array with CSV data, or false on failure
*/
function parse_string ($data = null) {
if ( empty($data) ) {
if ( $this->_check_data() ) {
$data = &$this->file_data;
} else return false;
}

$rows = array();
$row = array();
$row_count = 0;
$current = ”;
$head = ( !empty($this->fields) ) ? $this->fields : array() ;
$col = 0;
$enclosed = false;
$was_enclosed = false;
$strlen = strlen($data);

// walk through each character
for ( $i=0; $i < $strlen; $i++ ) {
$ch = $data{$i};
$nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
$pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;

// open and closing quotes
if ( $ch == $this->enclosure && (!$enclosed || $nch != $this->enclosure) ) {
$enclosed = ( $enclosed ) ? false : true ;
if ( $enclosed ) $was_enclosed = true;

// inline quotes
} elseif ( $ch == $this->enclosure && $enclosed ) {
$current .= $ch;
$i++;

// end of field/row
} elseif ( ($ch == $this->delimiter || ($ch == “\n” && $pch != “\r”) || $ch == “\r”) && !$enclosed ) {
if ( !$was_enclosed ) $current = trim($current);
$key = ( !empty($head[$col]) ) ? $head[$col] : $col ;
$row[$key] = $current;
$current = ”;
$col++;

// end of row
if ( $ch == “\n” || $ch == “\r” ) {
if ( $this->_validate_offset($row_count) && $this->_validate_row_conditions($row, $this->conditions) ) {
if ( $this->heading && empty($head) ) {
$head = $row;
} elseif ( empty($this->fields) || (!empty($this->fields) && (($this->heading && $row_count > 0) || !$this->heading)) ) {
if ( !empty($this->sort_by) && !empty($row[$this->sort_by]) ) {
if ( isset($rows[$row[$this->sort_by]]) ) {
$rows[$row[$this->sort_by].’_0′] = &$rows[$row[$this->sort_by]];
unset($rows[$row[$this->sort_by]]);
for ( $sn=1; isset($rows[$row[$this->sort_by].’_’.$sn]); $sn++ ) {}
$rows[$row[$this->sort_by].’_’.$sn] = $row;
} else $rows[$row[$this->sort_by]] = $row;
} else $rows[] = $row;
}
}
$row = array();
$col = 0;
$row_count++;
if ( $this->sort_by === null && $this->limit !== null && count($rows) == $this->limit ) {
$i = $strlen;
}
}

// append character to current field
} else {
$current .= $ch;
}
}
$this->titles = $head;
if ( !empty($this->sort_by) ) {
( $this->sort_reverse ) ? krsort($rows) : ksort($rows) ;
if ( $this->offset !== null || $this->limit !== null ) {
$rows = array_slice($rows, ($this->offset === null ? 0 : $this->offset) , $this->limit, true);
}
}
return $rows;
}

/**
* Create CSV data from array
* @param   data        2D array with data
* @param   fields      field names
* @param   append      if true, field names will not be output
* @param   is_php      if a php die() call should be put on the first
*                      line of the file, this is later ignored when read.
* @param   delimiter   field delimiter to use
* @return  CSV data (text string)
*/
function unparse ( $data = array(), $fields = array(), $append = false , $is_php = false, $delimiter = null) {
if ( !is_array($data) || empty($data) ) $data = &$this->data;
if ( !is_array($fields) || empty($fields) ) $fields = &$this->titles;
if ( $delimiter === null ) $delimiter = $this->delimiter;

$string = ( $is_php ) ? “<?php header(‘Status: 403’); die(‘ ‘); ?>”.$this->linefeed : ” ;
$entry = array();

// create heading
if ( $this->heading && !$append ) {
foreach( $fields as $key => $value ) {
$entry[] = $this->_enclose_value($value);
}
$string .= implode($delimiter, $entry).$this->linefeed;
$entry = array();
}

// create data
foreach( $data as $key => $row ) {
foreach( $row as $field => $value ) {
$entry[] = $this->_enclose_value($value);
}
$string .= implode($delimiter, $entry).$this->linefeed;
$entry = array();
}

return $string;
}

/**
* Load local file or string
* @param   input   local CSV file
* @return  true or false
*/
function load_data ($input = null) {
$data = null;
$file = null;
if ( $input === null ) {
$file = $this->file;
} elseif ( file_exists($input) ) {
$file = $input;
} else {
$data = $input;
}
if ( !empty($data) || $data = $this->_rfile($file) ) {
if ( $this->file != $file ) $this->file = $file;
if ( preg_match(‘/\.php$/i’, $file) && preg_match(‘/<\?.*?\?>(.*)/ims’, $data, $strip) ) {
$data = ltrim($strip[1]);
}
if ( $this->convert_encoding ) $data = iconv($this->input_encoding, $this->output_encoding, $data);
if ( substr($data, -1) != “\n” ) $data .= “\n”;
$this->file_data = &$data;
return true;
}
return false;
}

// ==============================================
// —– [ Internal Functions ] —————–
// ==============================================

/**
* Validate a row against specified conditions
* @param   row          array with values from a row
* @param   conditions   specified conditions that the row must match
* @return  true of false
*/
function _validate_row_conditions ($row = array(), $conditions = null) {
if ( !empty($row) ) {
if ( !empty($conditions) ) {
$conditions = (strpos($conditions, ‘ OR ‘) !== false) ? explode(‘ OR ‘, $conditions) : array($conditions) ;
$or = ”;
foreach( $conditions as $key => $value ) {
if ( strpos($value, ‘ AND ‘) !== false ) {
$value = explode(‘ AND ‘, $value);
$and = ”;
foreach( $value as $k => $v ) {
$and .= $this->_validate_row_condition($row, $v);
}
$or .= (strpos($and, ‘0’) !== false) ? ‘0’ : ‘1’ ;
} else {
$or .= $this->_validate_row_condition($row, $value);
}
}
return (strpos($or, ‘1’) !== false) ? true : false ;
}
return true;
}
return false;
}

/**
* Validate a row against a single condition
* @param   row          array with values from a row
* @param   condition   specified condition that the row must match
* @return  true of false
*/
function _validate_row_condition ($row, $condition) {
$operators = array(
‘=’, ‘equals’, ‘is’,
‘!=’, ‘is not’,
‘<‘, ‘is less than’,
‘>’, ‘is greater than’,
‘<=’, ‘is less than or equals’,
‘>=’, ‘is greater than or equals’,
‘contains’,
‘does not contain’,
);
$operators_regex = array();
foreach( $operators as $value ) {
$operators_regex[] = preg_quote($value, ‘/’);
}
$operators_regex = implode(‘|’, $operators_regex);
if ( preg_match(‘/^(.+) (‘.$operators_regex.’) (.+)$/i’, trim($condition), $capture) ) {
$field = $capture[1];
$op = $capture[2];
$value = $capture[3];
if ( preg_match(‘/^([\’\”]{1})(.*)([\’\”]{1})$/i’, $value, $capture) ) {
if ( $capture[1] == $capture[3] ) {
$value = $capture[2];
$value = str_replace(“\\n”, “\n”, $value);
$value = str_replace(“\\r”, “\r”, $value);
$value = str_replace(“\\t”, “\t”, $value);
$value = stripslashes($value);
}
}
if ( array_key_exists($field, $row) ) {
if ( ($op == ‘=’ || $op == ‘equals’ || $op == ‘is’) && $row[$field] == $value ) {
return ‘1’;
} elseif ( ($op == ‘!=’ || $op == ‘is not’) && $row[$field] != $value ) {
return ‘1’;
} elseif ( ($op == ‘<‘ || $op == ‘is less than’ ) && $row[$field] < $value ) {
return ‘1’;
} elseif ( ($op == ‘>’ || $op == ‘is greater than’) && $row[$field] > $value ) {
return ‘1’;
} elseif ( ($op == ‘<=’ || $op == ‘is less than or equals’ ) && $row[$field] <= $value ) {
return ‘1’;
} elseif ( ($op == ‘>=’ || $op == ‘is greater than or equals’) && $row[$field] >= $value ) {
return ‘1’;
} elseif ( $op == ‘contains’ && preg_match(‘/’.preg_quote($value, ‘/’).’/i’, $row[$field]) ) {
return ‘1’;
} elseif ( $op == ‘does not contain’ && !preg_match(‘/’.preg_quote($value, ‘/’).’/i’, $row[$field]) ) {
return ‘1’;
} else {
return ‘0’;
}
}
}
return ‘1’;
}

/**
* Validates if the row is within the offset or not if sorting is disabled
* @param   current_row   the current row number being processed
* @return  true of false
*/
function _validate_offset ($current_row) {
if ( $this->sort_by === null && $this->offset !== null && $current_row < $this->offset ) return false;
return true;
}

/**
* Enclose values if needed
*  – only used by unparse()
* @param   value   string to process
* @return  Processed value
*/
function _enclose_value ($value = null) {
if ( $value !== null && $value != ” ) {
$delimiter = preg_quote($this->delimiter, ‘/’);
$enclosure = preg_quote($this->enclosure, ‘/’);
if ( preg_match(“/”.$delimiter.”|”.$enclosure.”|\n|\r/i”, $value) || ($value{0} == ‘ ‘ || substr($value, -1) == ‘ ‘) ) {
$value = str_replace($this->enclosure, $this->enclosure.$this->enclosure, $value);
$value = $this->enclosure.$value.$this->enclosure;
}
}
return $value;
}

/**
* Check file data
* @param   file   local filename
* @return  true or false
*/
function _check_data ($file = null) {
if ( empty($this->file_data) ) {
if ( $file === null ) $file = $this->file;
return $this->load_data($file);
}
return true;
}

/**
* Check if passed info might be delimiter
*  – only used by find_delimiter()
* @return  special string used for delimiter selection, or false
*/
function _check_count ($char, $array, $depth, $preferred) {
if ( $depth == count($array) ) {
$first = null;
$equal = null;
$almost = false;
foreach( $array as $key => $value ) {
if ( $first == null ) {
$first = $value;
} elseif ( $value == $first && $equal !== false) {
$equal = true;
} elseif ( $value == $first+1 && $equal !== false ) {
$equal = true;
$almost = true;
} else {
$equal = false;
}
}
if ( $equal ) {
$match = ( $almost ) ? 2 : 1 ;
$pref = strpos($preferred, $char);
$pref = ( $pref !== false ) ? str_pad($pref, 3, ‘0’, STR_PAD_LEFT) : ‘999’ ;
return $pref.$match.’.’.(99999 – str_pad($first, 5, ‘0’, STR_PAD_LEFT));
} else return false;
}
}

/**
* Read local file
* @param   file   local filename
* @return  Data from file, or false on failure
*/
function _rfile ($file = null) {
if ( is_readable($file) ) {
if ( !($fh = fopen($file, ‘r’)) ) return false;
$data = fread($fh, filesize($file));
fclose($fh);
return $data;
}
return false;
}

/**
* Write to local file
* @param   file     local filename
* @param   string   data to write to file
* @param   mode     fopen() mode
* @param   lock     flock() mode
* @return  true or false
*/
function _wfile ($file, $string = ”, $mode = ‘wb’, $lock = 2) {
if ( $fp = fopen($file, $mode) ) {
flock($fp, $lock);
$re = fwrite($fp, $string);
$re2 = fclose($fp);
if ( $re != false && $re2 != false ) return true;
}
return false;
}

}

?>

Advertisements
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Advertisements
%d bloggers like this: