web-dev-qa-db-fra.com

CSV à tableau associatif

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.

Par exemple:

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

Où créerait un tableau tel que Array[$num][$key]$key serait Marque, Modèle, Pièce, Test.

Donc, si je voulais accéder à la valeur de test "434", je devrais boucler tous les index du tableau, puis ignorer toutes les marques qui n'étaient pas Honda, et tous les modèles qui n'étaient pas Civic.


Ce que je dois faire, c'est accéder le plus directement à la valeur, au lieu de passer par une boucle for parcourant chaque index $ num. Je veux pouvoir accéder au test de valeur "434" avec:

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

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

foreach $model in Array['Honda']

À tout le moins, je dois pouvoir examiner chaque modèle avec une marque connue et accéder à toutes les informations relatives à chacun.

Modifier:

Juste pour confirmer que je montais ceci en exemple. Mes données ont des en-têtes comme:

brand model part price shipping description footnote

Dont je dois accéder à toutes les informations liées à la pièce (prix, expédition, description, note de bas de page)

33
ParoX

exécutez ligne par ligne le fichier csv et insérez-le dans un tableau comme suit:

$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);
}
50
Haim Evgi

Trop de solutions longues. J'ai toujours trouvé que c'était 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);
    }
?>
48
Daerik

Pour créer un tableau de liste associatif, utilisez 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;
         }
    }
}

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

16
mario

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);
4
Tom Carnell

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 cet usage:

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

Utiliser fgetcsv() semble être l'outil le plus direct et le plus pratique pour le travail.

contenu csv.csv:

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>";

Sortie:

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',
  ),
)

Ressource: http://php.net/manual/en/function.fgetcsv.php

0
mickmackusa