2011-01-26 3 views
26

J'ai vu de nombreux exemples sur la façon de prendre un fichier CSV, puis de créer un tableau associatif avec les en-têtes comme clés.CSV à Array associatif

Par exemple:

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

Où il créer un tableau tel que Array[$num][$key]$key serait Marque, modèle, partie, Test.

Donc, si je voulais accéder à la valeur de test « 434 » je dois boucle tous les index dans le tableau, puis ignorer toutes les marques qui ne sont pas honda, et tous les modèles qui ne sont pas Civic


Ce que je dois faire, c'est accéder directement à la valeur, au lieu de passer par une boucle for passant par chaque index $ num. Je veux être en mesure d'accéder au test de valeur "434" avec:

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

ou contrôler une déclaration pour avec une boucle à travers tous les modèles Honda a ... quelque chose comme

foreach $model in Array['Honda']

À tout le moins, je dois être en mesure de passer en revue chaque modèle donné une marque connue et accéder à toutes les informations relatives à chacun.

Edit:

Juste pour confirmer que je mettre cela en place un exemple. Mon fait des données a en-têtes comme:

brand model part price shipping description footnote

dont je besoin d'accéder à toutes les informations liées à la partie (prix, expédition, desc, note)

+1

[Exemple (s) comment faire avec 'SplFileInfo'] (http://stackoverflow.com/a/10181302/367456) – hakre

Répondre

48

course sur la ligne de fichier csv par ligne et insérer à tableau comme:

$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

Works pour la Par exemple, l'OP a donné, mais méfiez-vous que les fichiers CSV peuvent avoir des virgules dans les champs de texte comme suit: field1, "field two", "field, 3", field4. – xelco52

+1

@ xelco52: 'fgetcsv()' gérera cela très bien. – BoltClock

+0

vous droite je change à fgetcsv –

15

pour créer un tableau de liste associative utiliser quelque chose comme:

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

Et pour parcourir et filtrer par attributs spécifiques écrire une fonction comme:

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

Si vous invoquer avec $find = array(Brand=>Honda, Model=>Civic, Part=>135) pour filtrer les modèles recherchés. L'autre structure de tableau de position ne semble pas très pratique, sauf si vous voulez seulement accéder à l'attribut "Test".

2

Voici une solution qui fonctionnera en spécifiant un fichier local ou une URL. Vous pouvez également activer et désactiver l'association. Espérons que cela aide.

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

Essayez cette utilisation:

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

blog link is dead –

4

Essayez cet algorithme simple:

 $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

Trop de solutions à long.Je l'ai toujours trouvé que ce soit le plus 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 et dynamique - excellente solution. Merci! – domdambrogia

+0

Merci mon pote, une excellente solution. – GuRu

+0

Cela a fonctionné très bien, je n'ai jamais utilisé la moissonneuse-batteuse, mais cela a fonctionné génial! Je vous remercie! –