I\'ve seen numerous examples on how to take a CSV file and then create an associative array with the headers as the keys.
For example:
Brand,Model,Pa
Try this simple algorithm:
$assocData = array();
if( ($handle = fopen( $importedCSVFile, "r")) !== FALSE) {
$rowCounter = 0;
while (($rowData = fgetcsv($handle, 0, ",")) !== FALSE) {
if( 0 === $rowCounter) {
$headerRecord = $rowData;
} else {
foreach( $rowData as $key => $value) {
$assocData[ $rowCounter - 1][ $headerRecord[ $key] ] = $value;
}
}
$rowCounter++;
}
fclose($handle);
}
var_dump( $assocData);
Here is a solutions that will work by specifying a local file or URL. You can also switch the association on and off. Hopefully this helps.
class CSVData{
public $file;
public $data;
public $fp;
public $caption=true;
public function CSVData($file=''){
if ($file!='') getData($file);
}
function getData($file){
if (strpos($file, 'tp://')!==false){
copy ($file, '/tmp/csvdata.csv');
if ($this->fp=fopen('/tmp/csvdata.csv', 'r')!==FALSE){
$this->readCSV();
unlink('tmp/csvdata.csv');
}
} else {
$this->fp=fopen($file, 'r');
$this->readCSV();
}
fclose($this->fp);
}
private function readCSV(){
if ($this->caption==true){
if (($captions=fgetcsv($this->fp, 1000, ","))==false) return false;
}
$row=0;
while (($data = fgetcsv($this->fp, 1000, ",")) !== FALSE) {
for ($c=0; $c < count($data); $c++) {
$this->data[$row][$c]=$data[$c];
if ($this->caption==true){
$this->data[$row][$captions[$c]]=$data[$c];
}
}
$row++;
}
}
}
Try this usage:
$o=new CSVData();
$o->getData('/home/site/datafile.csv');
$data=$o->data;
print_r($data);
To create an associative list array use something like:
$keys = fgetcsv($f);
while (!feof($f)) {
$array[] = array_combine($keys, fgetcsv($f));
}
And to traverse and filter by specific attributes write a function like:
function find($find) {
foreach ($array as $row) {
if (array_intersect_assoc($row, $find) == $find) {
$result[] = $row;
}
}
}
Where you would invoke it with $find = array(Brand=>Honda, Model=>Civic, Part=>135)
to filter out the searched models. The other positional array structure seems not very workable, unless you only want to access the "Test" attribute.
Too many long solutions. I've always found this to be the simplest:
<?php
/* Map Rows and Loop Through Them */
$rows = array_map('str_getcsv', file('file.csv'));
$header = array_shift($rows);
$csv = array();
foreach($rows as $row) {
$csv[] = array_combine($header, $row);
}
?>
run over the csv file line by line, and insert to array like:
$array = $fields = array(); $i = 0;
$handle = @fopen("file.csv", "r");
if ($handle) {
while (($row = fgetcsv($handle, 4096)) !== false) {
if (empty($fields)) {
$fields = $row;
continue;
}
foreach ($row as $k=>$value) {
$array[$i][$fields[$k]] = $value;
}
$i++;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
Using fgetcsv()
seems the most direct and sensible tool for the job.
csv.csv contents:
Brand,Model,Part,Test
Honda,Civic,123,244
Honda,Civic,135,434
Toyota,Supra,511,664
Code:
$assoc_array = [];
if (($handle = fopen("csv.csv", "r")) !== false) { // open for reading
if (($data = fgetcsv($handle, 1000, ",")) !== false) { // extract header data
$keys = $data; // save as keys
}
while (($data = fgetcsv($handle, 1000, ",")) !== false) { // loop remaining rows of data
$assoc_array[] = array_combine($keys, $data); // push associative subarrays
}
fclose($handle); // close when done
}
echo "<pre>";
var_export($assoc_array); // print to screen
echo "</pre>";
Output:
array (
0 =>
array (
'Brand' => 'Honda',
'Model' => 'Civic',
'Part' => '123',
'Test' => '244',
),
1 =>
array (
'Brand' => 'Honda',
'Model' => 'Civic',
'Part' => '135',
'Test' => '434',
),
2 =>
array (
'Brand' => 'Toyota',
'Model' => 'Supra',
'Part' => '511',
'Test' => '664',
),
)
Resource: http://php.net/manual/en/function.fgetcsv.php