note 88616 modified in function.fgetcsv by danbrown

From: 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

« previous php.notes (#151565) next »