2011-01-26 21 views
26

He visto numerosos ejemplos sobre cómo tomar un archivo CSV y luego crear una matriz asociativa con los encabezados como las claves.CSV a Matriz Asociativa

Por ejemplo:

Brand,Model,Part,Test 
Honda,Civic,123,244 
Honda,Civic,135,434 
Toyota,Supra,511,664 

en la que crearía una matriz como Array[$num][$key] donde $key habría marca, modelo, Parte, Prueba.

así que si quería tener acceso al valor de prueba "434" Tendría que bucle de cada índice de la matriz y luego ignorar las marcas que no eran Honda, y cualquiera de los modelos que no eran Cívico


Lo que tengo que hacer es acceder al valor más directamente, en lugar de ejecutar un bucle for pasando por cada índice de $ num. Quiero ser capaz de acceder a la prueba de valor "434" con:

Array['Honda']['Civic']['135']

o controlar una instrucción con bucle a través de todos los modelos de Honda tiene ... algo así como

foreach $model in Array['Honda']

Por lo menos, necesito poder revisar cada modelo de una marca conocida y acceder a toda la información relativa de cada uno.

Editar:

sólo para confirmar que estaba configurar esto un ejemplo. Mi realidad los datos tiene encabezados como:

brand model part price shipping description footnote

De los que necesito para acceder a toda la información vinculada a la parte (precio, el envío, la descripción, nota)

+1

[Ejemplo (s) cómo hacerlo con 'SplFileInfo'] (http://stackoverflow.com/a/10181302/367456) Obras para la – hakre

Respuesta

48

carrera en la línea de archivo csv por la línea , e insertar a la matriz como:

$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); 
} 
+0

ejemplo, el OP dio, pero tenga cuidado de que los archivos csv pueden tener comas en campos de texto como: campo1, "campo dos", "campo, 3", campo4. – xelco52

+1

@ xelco52: 'fgetcsv()' lo manejará bien. – BoltClock

+0

tienes derecho a cambiar a fgetcsv –

15

para crear una matriz asociativa lista usar algo como:

$keys = fgetcsv($f); 
while (!feof($f)) { 
    $array[] = array_combine($keys, fgetcsv($f)); 
} 

Y para atravesar y filtrar por atributos específicos escribir una función como:

function find($find) { 
    foreach ($array as $row) { 
     if (array_intersect_assoc($row, $find) == $find) { 
      $result[] = $row; 
     } 
    } 
} 

Dónde debe invocar con $find = array(Brand=>Honda, Model=>Civic, Part=>135) para filtrar los modelos buscado. La otra estructura de matriz posicional parece poco viable, a menos que solo desee acceder al atributo "Prueba".

2

Aquí hay una solución que funcionará especificando un archivo local o una URL. También puede activar y desactivar la asociación. Espero que esto ayude.

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++; 
     } 
    } 
} 

probar este uso:

$o=new CSVData(); 
$o->getData('/home/site/datafile.csv'); 
$data=$o->data; 
print_r($data); 
+0

enlace de blog está muerto –

4

probar este sencillo algoritmo:

 $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); 
23

demasiadas soluciones de largo.Siempre he encontrado que este es el más simple:

<?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); 
    } 
?> 
+0

Simple y dinámico - gran solución. ¡Gracias! – domdambrogia

+0

Gracias amigo, gran solución. – GuRu

+0

Esto funcionó muy bien, nunca utilicé la combinación de arreglos, ¡pero funcionó de maravilla! ¡Gracias! –