CSV au 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ù il créerait un tableau tel que Array[$num][$key] où {[2] } serait Brand, Model, Part, 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 est accédez à la valeur le plus directement, au lieu de parcourir une boucle for en passant par chaque index $num. Je veux pouvoir accéder au test de valeur " 434 " avec:

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

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

foreach $model in Array['Honda']

À tout le moins, je dois être capable de parcourir chaque modèle donné une marque connue et d'accéder à toutes les informations relatives à chacun.

Modifier:

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

brand model part price shipping description footnote

Dont j'ai besoin pour accéder à toutes les informations liées à la partie (Prix, expédition,desc, note de bas de page)

32
demandé sur ParoX 2011-01-26 09:29:05

5 réponses

Exécutez le fichier csv ligne par ligne, et insérez dans le 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);
}
48
répondu Haim Evgi 2016-01-08 15:16:38

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);
    }
?>
45
répondu Daerik 2017-01-30 17:50:55

Pour créer un tableau de liste associative, utilisez quelque chose comme:

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

Et pour traverser et filtrer par des attributs spécifiques, écrivez 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 positionnel ne semble pas très réalisable, sauf si vous voulez seulement accéder à l'attribut" Test".

16
répondu mario 2011-01-26 06:46:29

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
répondu Tom Carnell 2012-01-14 11:52:20

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);
2
répondu Brad 2016-11-11 07:07:46