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
define('ON_COLLISION_OVERWRITE', 1);
define('ON_COLLISION_SKIP' , 2);
define('ON_COLLISION_ABORT' , 3);
function read_lookup_table_from_csv( $csv_file
, $separator_input = ';'
, $separator_index = '|'
, $index_by = array(0 => '')
, $on_collision = ON_COLLISION_ABORT
, $rec_len = 1024
)
{
$handle = fopen($csv_file, 'r');
if($handle == null || ($data = fgetcsv($handle, $rec_len, $separator_input)) === false)
{
return -1;
}
$names = array();
foreach($data as $field)
{
$names[] = trim($field);
}
$indexes = array();
foreach($index_by as $index_in => $function)
{
if(is_int($index_in))
{
if($index_in < 0 || $index_in > count($data))
{
fclose($handle);
return -2;
}
$index_out = $index_in;
}
else
{
$get_index = array_keys($names, $index_in);
$index_out = $get_index[0];
if(is_null($index_out))
{
fclose($handle);
return -3;
}
}
$indexes[$index_out] = $function;
}
if(count($indexes) == 0)
{
fclose($handle);
return -4;
}
$retval = array();
while(($data = fgetcsv($handle, $rec_len, $separator_input)) !== false)
{
$index_by = '';
foreach($indexes as $index => $function)
{
$index_by .= ($function ? $function($data[$index]) : $data[$index]) . $separator_index;
}
$index_by = substr($index_by, 0, -1);
if(isset($retval[$index_by]))
{
switch($on_collision)
{
case ON_COLLISION_OVERWRITE : $retval[$index_by] = array_combine($names, $data);
case ON_COLLISION_SKIP : break;
case ON_COLLISION_ABORT : return -5;
}
}
else
{
$retval[$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,
<?php
$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.
<?php
echo 'The name of day #3 is ', $days[3]['DayName'];
?>
Alternatively, you can use the function like this
<?php
$days = read_lookup_table_from_csv('DaysOfWeek.csv', 'DayName');
echo 'The abbreviation of Friday is ', $days['Friday']['DayAbbr'];
?>
or like this
<?php
$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.]