note 88616 modified in function.fgetcsv by danbrown
| From: | danbrown@php.net | Date: | Fri, 06 Mar 2009 17:32:49 +0000 |
| Subject: | note 88616 modified in function.fgetcsv by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-151565@lists.php.net to get a copy of this message | ||
Currently, I'm working on a script that takes data exported from one database and converts it
so that it can be imported in another. I have been given a bunch of CSV files containing data to
make the translation possible --actually, the values are semi-colon separated, not comma-separated.
The following script reads a CSV file with field names on the first line (for an example, see below
the script), and turns it into a hash table where the key is one of the fields.
<?php
/**
* Reads a CSV file and stores it as a lookup table, implemented as a PHP hash table.
*
* @param string $csv_file the CSV file to read.
* @param mixed $index_by the column name (string) ort number (integer) to index the lookup
table by.
* @param string $separator the character that is used in the CSV file as field separator.
* @param integer $rec_len the maximum length of a record in the input file.
* @return mixed an error number or the resulting hash table.
*/
function read_lookup_table_from_csv($csv_file, $index_by = 0, $separator = ';', $rec_len =
1024)
{
$handle = fopen($csv_file, 'r');
if($handle == null || ($data = fgetcsv($handle, $rec_len, $separator)) === false)
{
// Couldn't open/read from CSV file.
return -1;
}
$names = array();
foreach($data as $field)
{
$names[] = trim($field);
}
if(is_int($index_by))
{
if($index_by < 0 || $index_by > count($data))
{
// Index out of bounds.
fclose($handle);
return -2;
}
}
else
{
// If the column to index by is given as a name rather than an integer, then
// determine that named column's integer index in the $names array, because
// the integer index is used, below.
$get_index = array_keys($names, $index_by);
$index_by = $get_index[0];
if(is_null($index_by))
{
// A column name was given (as opposed to an integer index), but the
// name was not found in the first row that was read from the CSV file.
fclose($handle);
return -3;
}
}
$retval = array();
while(($data = fgetcsv($handle, $rec_len, $separator)) !== false)
{
$retval[trim($data[$index_by])] = array_combine($names, $data);
}
fclose($handle);
return $retval;
}
?>
Assume the CSV file DaysOfWeek.csv contains this:
DayNo;DayName;DayAbbr
0;Sunday;Sun
1;Monday;Mon
2;Tuesday;Tue
3;Wednesday;Wed
4;Thursday;Thu
5;Friday;Fri
6;Saturday;Sat
(Reproduced in full as a service to you, dear reader, so you can more easily test the script if you
wish. :-)
Now,
$days = read_lookup_table_from_csv('DaysOfWeek.csv');
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 0);
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 'DayNo');
will all read the file, and index it using the contents of the zero'th column as an index.
echo 'The name of day #3 is ', $days[3]['DayName'];
Alternatively, you can use the function like this
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 'DayName');
echo 'The abbreviation of Friday is ', $days['Friday']['DayAbbr'];
or like this
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 'DayAbbr');
echo 'The full name of Fri is ', $days['Fri']['DayName'];
Typically, of course, the first index to $days will be a variable rather than a literal/constant,
allowing for easy translation of one value to another.
[EDIT BY danbrown AT php DOT net: Updated by the original poster on 2009-03-06 to fix two typos.]
--was--
Currently, I'm working on a script that takes data exported from one database and converts it
so that it can be imported in another. I have been given a bunch of CSV files containing data to
make the translation possible --actually, the values are semi-colon separated, not comma-separated.
The following script reads a CSV file with field names on the first line (for an example, see below
the script), and turns it into a hash table where the key is one of the fields.
<?php
/**
* Reads a CSV file and stores it as a lookup table, implemented as a PHP hash table.
*
* @param string $csv_file the CSV file to read.
* @param mixed $index_by the column name (string) ort number (integer) to index the lookup
table by.
* @param string $separator the character that is used in the CSV file as field separator.
* @param integer $rec_len the maximum length of a record in the input file.
* @return mixed an error number or the resulting hash table.
*/
function read_lookup_table_from_csv($csv_file, $index_by = 0, $separator = ';', $rec_len =
1024)
{
$handle = fopen($csv_file, 'r');
if($handle == null || ($data = fgetcsv($handle, $rec_len, $separator)) === false)
{
// Couldn't open/read from CSV file.
return -1;
}
$names = array();
foreach($data as $field)
{
$names[] = trim($field);
}
if(is_int($index_by))
{
if($index_by < 0 || $index_by > count($data))
{
// Index out of bounds.
fclose($handle);
return -2;
}
}
else
{
// If the column to index by is given as a name rather than an integer, then
// determine that named column's integer index in the $names array, because
// the integer index is used, below.
$get_index = array_keys($names, $index_by);
$index_by = $get_index[0];
if(is_null($index_by))
{
// A column name was given (as opposed to an integer index), but the
// name was not found in the first row that was read from the CSV file.
fclose($handle);
return -3;
}
}
$retval = array();
while(($data = fgetcsv($handle, $rec_len, $separator)) !== false)
{
$retval[trim($data[$index_by])] = array_combine($names, $data);
}
fclose($handle);
return $retval;
}
?>
Assume the CSV file DaysOfWeek.csv contains this:
DayNo;DayName;DayAbbr
0;Sunday;Sun
1;Monday;Mon
2;Tuesday;Tue
3;Wednesday;Wed
4;Thursday;Thu
5;Friday;Fri
6;Saturday;Sat
(Reproduced in full as a service to you, dear reader, so you can more easily test the script if you
wish. :-)
Now,
$days = read_lookup_table_from_csv('DaysOfWeek.csv');
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 0);
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 'DayNo');
will all read the file, and index it using the contents of the zero'th column as an index.
echo 'The name of day #3 is ', $days[3]['Name'];
Alternatively, you can use the function like this
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 'DayName');
echo 'The abbreviation of Friday is ', $days['Friday']['DayAbbr'];
or like this
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 'DayAbbr');
echo 'The full name of Fri is ', $days['Fri']['Name'];
Typically, of course, the first index to $days will be a variable rather than a literal/constant,
allowing for easy translation of one value to another.
http://php.net/manual/en/function.fgetcsv.php