This does the same as the example below, giving you an array, but it allows to parse csv with commas in between quotes (used for addresses)... and it takes out the quotes from an array entry as well.
<?php
function parse_csv($file, $options = null) {
$delimiter = empty($options['delimiter']) ? "," : $options['delimiter'];
$to_object = empty($options['to_object']) ? false : true;
$expr="/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/"; // added
$str = $file;
$lines = explode("\n", $str);
$field_names = explode($delimiter, array_shift($lines));
foreach ($lines as $line) {
// Skip the empty line
if (empty($line)) continue;
$fields = preg_split($expr,trim($line)); // added
$fields = preg_replace("/^\"(.*)\"$/","$1",$fields); //added
//$fields = explode($delimiter, $line);
$_res = $to_object ? new stdClass : array();
foreach ($field_names as $key => $f) {
if ($to_object) {
$_res->{$f} = $fields[$key];
} else {
$_res[$f] = $fields[$key];
}
}
$res[] = $_res;
}
return $res;
}
?>
str_getcsv
(No version information available, might be only in CVS)
str_getcsv — Analisa uma string CSV e retorna os dados em um array
Descrição
array str_getcsv
( string $input
[, string $delimiter
[, string $enclosure
[, string $escape
]]] )
Aviso
Esta função não está documentada; somente a lista de argumentos está disponível.
str_getcsv
Rob
07-Nov-2008 08:54
07-Nov-2008 08:54
william dot j dot weir at gmail dot com
18-Sep-2008 03:19
18-Sep-2008 03:19
If your happy enough having just a multi-dimensional array, this should work fine. I had wanted to use the one provided by keananda but it was choking on pr($lines).
<?php
function f_parse_csv($file, $longest, $delimiter) {
$mdarray = array();
$file = fopen($file, "r");
while ($line = fgetcsv($file, $longest, $delimiter)) {
array_push($mdarray, $line);
}
fclose($file);
return $mdarray;
}
?>
$longest is a number that represents the longest line in the csv file as required by fgetcsv(). The page for fgetcsv() said that the longest line could be set to 0 or left out, but I couldn't get it to work without. I just made it extra large when I had to use it.
keananda at gmail dot com
15-Sep-2008 04:29
15-Sep-2008 04:29
For those who need this function but not yet installed in their environment, you can use my function bellow.
You can parse your csv file into an associative array (by default) for each lines, or into an object.
<?php
function parse_csv($file, $options = null) {
$delimiter = empty($options['delimiter']) ? "," : $options['delimiter'];
$to_object = empty($options['to_object']) ? false : true;
$str = file_get_contents($file);
$lines = explode("\n", $str);
pr($lines);
$field_names = explode($delimiter, array_shift($lines));
foreach ($lines as $line) {
// Skip the empty line
if (empty($line)) continue;
$fields = explode($delimiter, $line);
$_res = $to_object ? new stdClass : array();
foreach ($field_names as $key => $f) {
if ($to_object) {
$_res->{$f} = $fields[$key];
} else {
$_res[$f] = $fields[$key];
}
}
$res[] = $_res;
}
return $res;
}
?>
NOTE:
Line number 1 of the csv file will be considered as header (field names).
TODO:
- Enclosure handling
- Escape character handling
- Other features/enhancements as you need
EXAMPLE USE:
Content of /path/to/file.csv:
CODE,COUNTRY
AD,Andorra
AE,United Arab Emirates
AF,Afghanistan
AG,Antigua and Barbuda
<?php
$arr_csv = parse_csv("/path/to/file.csv");
print_r($arr_csv);
?>
// Output:
Array
(
[0] => Array
(
[CODE] => AD
[COUNTRY] => Andorra
)
[1] => Array
(
[CODE] => AE
[COUNTRY] => United Arab Emirates
)
[2] => Array
(
[CODE] => AF
[COUNTRY] => Afghanistan
)
[3] => Array
(
[CODE] => AG
[COUNTRY] => Antigua and Barbuda
)
)
<?php
$obj_csv = parse_csv("/path/to/file.csv", array("to_object" => true));
print_r($obj_csv);
?>
// Output:
Array
(
[0] => stdClass Object
(
[CODE] => AD
[COUNTRY] => Andorra
)
[1] => stdClass Object
(
[CODE] => AE
[COUNTRY] => United Arab Emirates
)
[2] => stdClass Object
(
[CODE] => AF
[COUNTRY] => Afghanistan
)
[3] => stdClass Object
(
[CODE] => AG
[COUNTRY] => Antigua and Barbuda
)
[4] => stdClass Object
(
[CODE] =>
[COUNTRY] =>
)
)
// If you use character | (pipe) as delimiter in your csv file, use:
<?php
$arr_csv = parse_csv("/path/to/file.csv", array("delimiter"=>"|"));
?>
==NSD==
lgandras at hotmail dot com
25-Aug-2008 03:47
25-Aug-2008 03:47
peev[dot]alexander at gmail dot com, please do keep in mind that:
$thisIsTrue= '\\"' == '\"';
PHP is not capable of telling you if you are escaping a string with a backslash or if that backslash is being escaped. Both strings have length 2. First character is '\' and second is '"'. On second example quote is being escaped while on first example they are being not.
colin_mckinnon at slc dot co dot uk
09-Jun-2008 09:00
09-Jun-2008 09:00
Regarding RFC 4180 - I asked the author about the specifics of the format described which poses a number of technical difficulties in building a parser - his response is shown below:
quote:
Please do keep one thing in mind - this RFC
was meant to define the MIME type for CSV rather than the format. It
happens to be that no format definition existed and I was forced to
define one. As the RFC states:
"This section documents the format that seems to be followed by most
implementations"
csv at rfc dot org
05-May-2008 01:15
05-May-2008 01:15
RFC 4180 which deals with CSVs states the escape character is supposed to be a double quotation mark: (page 2)
7. If double-quotes are used to enclose fields, then a double-quote
appearing inside a field must be escaped by preceding it with
another double quote. For example:
"aaa","b""bb","ccc"
peev[dot]alexander at gmail dot com
20-Apr-2008 02:22
20-Apr-2008 02:22
CSV parsing and storage is not that hard to implement - see my example functions ( I believe they do a pretty good job - I use them in a production environment ):
<?php
if( !function_exists("parse_csv") ){
function parse_csv($string){
/* Author : Alexander Peev, posted at PHP.NET */
if( !function_exists("parse_csv_aux") ){
function parse_csv_aux( $string ){
$product = "";
$in_quote = FALSE;
$skipped_quote = FALSE;
for( $i = 0 ; $i < strlen($string) ; $i++ ){
if( $string{$i} == "\"" ){
if($in_quote){
if($skipped_quote){
$product .= "\"";
$skipped_quote = FALSE;
}
else if( !$skipped_quote ){
$skipped_quote = TRUE;
}
}
else{
if($skipped_quote) $skipped_quote = FALSE;
$in_quote = TRUE;
}
}
else if( $string{$i} == ";" ){
if($in_quote){
$product .= ";";
}
else{
$product .= " ; ";
}
}
else{
if($in_quote){
$in_quote = FALSE;
$product .= $string{$i};
}
else{
$product .= $string{$i};
}
}
}
return $product;
}
}
$data = array();
if( is_string($string) && ( stripos($string, "\n") !== FALSE ) ){
$data = explode("\n", parse_csv_aux($string) );
foreach($data as $key => $row){
$columns = array();
//$row = strtr( $row, array( "\";\"" => "\";\"", ";" => " ; " ) );
if( stripos($row, " ; ") !== FALSE ){
$columns = explode( " ; ", $row );
if( !is_array($columns) )$columns = array( strval($columns) );
$data[$key] = $columns;
}
}
return $data;
}
else if( is_string($string) && ( stripos( ($string = parse_csv_aux($string)), " ; ") !== FALSE ) ){
$columns = explode( " ; ", $string );
if( !is_array($columns) )$columns = array( strval($columns) );
return array($columns);
}
else return strval($string);
} /* end function parse_csv */
} /* end not function exists parse_csv */
if( !function_exists("store_csv") ){
function store_csv($data){
/* Author : Alexander Peev, posted at PHP.NET */
if( !function_exists("store_csv_aux") ){
function store_csv_aux( $string ){
$string = strtr( $string, array( "\n" => "" ) );
$product = "";
$in_quote = FALSE;
for( $i = 0 ; $i < strlen($string) ; $i++ ){
if( $string{$i} == "\"" ){
if($in_quote){
$product .= "\"\"";
}
else{
$product .= "\"\"\"";
$in_quote = TRUE;
}
}
else if( $string{$i} == ";" ){
if($in_quote){
$product .= ";";
}
else{
$product .= "\";";
$in_quote = TRUE;
}
}
else{
if($in_quote){
$product .= "\"";
$in_quote = FALSE;
$product .= $string{$i};
}
else{
$product .= $string{$i};
}
}
}
if($in_quote)$product .= "\"";
return $product;
}
}
if(!is_array($data))return strval($data);
$passed_rows = FALSE;
$product = "";
foreach($data as $row){
if( $passed_rows )$product .= "\n";
if( is_array($row) ){
$columns = "";
$passed_cols = FALSE;
foreach($row as $column){
if( $passed_cols )$columns .= ";";
$columns .= store_csv_aux( $column );
$passed_cols =TRUE;
}
$product .= strval($columns);
}
else{
$product .= strtr( strval($row), array("\n" => "") );
}
$passed_rows = TRUE;
}
return $product;
} /* end function store_csv */
} /* end not function exists store_csv */
?>
jon at webignition dot net
04-Apr-2008 03:52
04-Apr-2008 03:52
Parameter documentation, currently missing here, can be found at:
> http://www.php.net/manual/en/function.fgetcsv.php
justin at cam dot org
15-Feb-2007 10:25
15-Feb-2007 10:25
There's a discussion of how to perform this task in the user notes for the split() function.
http://www.php.net/manual/en/function.split.php
