CSV to Array

The Scenario

Across a legacy code base, you may often find instances where a .csv file is read in and often stored in a database or otherwise used. In my case, it has (almost) always been that the resulting array from str_getcsv() winds up getting walked and stored into a new array as associative rows. Other times, the resulting rows are directly used in a database insert as flat arrays, and when one row is a column short, we’re in debugging and looking for errors. One of the most tedious things I have found about this is we wind up counting columns, seeing which matches which in the header, to find the missing value.

I call the CsvToArray object a wrapper object for str_getcsv(), but it’s actually a little more than that. It validates that the columns match the headers and returns an associative array for each row, keyed on the CSV header. Wherever I read a CSV, it now will throw an error before the result is actually used, as in a database insert or update. Since the arrays are associative, if there is a column mismatch I can see exactly which column is missing.

First have a look at the demo to see it at work.

The Logic

The CsvToArray object is instantiated with the path to the .csv file, delimiter, and enclosure (also known as "qualifier.") Delimiter defaults to comma and qualifier empty. The file path is sent to SplFileObject, offloading all the usual validation of reading a file. str_getcsv() is applied on SplFileObject to initially create a template array containing the headers found in the first line. As we walk through the CSV rows, this template is used to create the associative array returned by the public parseData() method.

The one dependency is that the CSV must contain a header row.

The Code and Structure

Usage is pretty simple:

<?php
/**
 * @return array
 * [
 *  'errors' => [],
 *  'data'  => [
 *    [int row index] => [
 *      [string field] => [mixed value],
 *      ....
 *    ]
 *  ];
 */
$csv        = '/full/path/to/your-csv.csv';
$delimiter  = ',';
$qualifier  = '"';
try {
    $CsvToArray = new CsvToArray($csv, $delimiter, $qualifier);
    $data_array = $CsvToArray->getCsvArray();
} catch (Exception $e) {
    // Do something with $e->getMessage()
}
// Do something useful with $data_array

That’s really all there is to it! It’s all in the demo. I have used it to generate large amounts of data wherever search functionality or pagination testing is required. You’ll see this object in use in a couple other projects.