Bonjour à tous!
Aujourd'hui, j'aurais besoins de convertir un fichier csv en dictionnaire php (s'était beaucoup plus simple en node.js mais j'ai baissé les bras). J'ai réussi à faire de mon fichier csv un array mais je n'arrives pas à aller plus loin ...
Un fichier csv similaire au mien :

id;nom;prenom
1;Jack;Dupont
2;George;Sansnom

ce qui donnerait :

{
     {
     "id" => "1",
     "nom" => "Jack",
     "prenom" => "Dupont",
     },
     {
     "id" => "2",
     "nom" => "George",
     "prenom" => "Sansnom",
     }
}


et voici le code que j'ai réussi à faire pour le moment (:

        $csv = []; 
        if (($e = fopen($user_file, "r")) !== FALSE) {
            while (($data = fgetcsv($e, 1000, ";")) !== FALSE) {
                $csv[] = $data;
            }
            fclose($e);
        }

        echo "<pre>";
        var_dump($csv);
        echo "</pre>";

Si quelqu'un saurait faire, je suis preneur! Bonne soirée à tous! (:
Modifié par vzytoi (14 Mar 2021 - 04:29)
Modérateur
Et l'eau,

Pourquoi tu ne le fais pas en python ? Smiley hum C'est tellement plus facile et tellement mieux !

import csv
with open('names.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        print(row['nom'], row['prenom'])


ps : php ne connait pas les dictionnaires, mais plutôt les array associatifs
Modifié par niuxe (14 Mar 2021 - 08:13)
Modérateur
Bonjour,

Voici ci-dessous une possibilité. J'ai choisi un tableau comme structure globale (c'est probablement le plus efficace), contenant des objects, 1 par ligne du dictionnaire. Au lieu de ces objets, on aurait pu mettre des tableaux associatifs : il suffit de supprimer le "(object)" dans la ligne "if($n) $csv[] = (object)array(".

J'ai ajouté un echo du json obtenu au cas où.

$user_file="myDict.csv";
$csv = []; 
if (($e = fopen($user_file, "r")) !== FALSE) {
	$n=0;
	while (($data = fgetcsv($e, 1000, ";")) !== FALSE) {
		if($n) $csv[] = (object)array(
			$data0[0]=>$data[0],
			$data0[1]=>$data[1],
			$data0[2]=>$data[2]
		);
		else {
			$data0=$data;
			$n=1;
		}
	}
	fclose($e);
}
echo "<pre>";
var_dump($csv);
echo "</pre>";
echo json_encode($csv);


Amicalement,
niuxe a écrit :
Et l'eau,

Pourquoi tu ne le fais pas en python ? Smiley hum C'est tellement plus facile et tellement mieux !

import csv
with open('names.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        print(row['nom'], row['prenom'])


ps : php ne connait pas les dictionnaires, mais plutôt les array associatifs

Merci beaucoup de ta réponse (:
J'aurais aussi aimé ne pas m'embêter avec du php mais ce serait pour convertir en "array associatif" un fichier csv rentré par un utilisateur dans un input type=file et mon site n'est pas en django/flask ...
Bonne journée à toi!
parsimonhi a écrit :
Bonjour,

Voici ci-dessous une possibilité. J'ai choisi un tableau comme structure globale (c'est probablement le plus efficace), contenant des objects, 1 par ligne du dictionnaire. Au lieu de ces objets, on aurait pu mettre des tableaux associatifs : il suffit de supprimer le "(object)" dans la ligne "if($n) $csv[] = (object)array(".

J'ai ajouté un echo du json obtenu au cas où.

$user_file="myDict.csv";
$csv = []; 
if (($e = fopen($user_file, "r")) !== FALSE) {
	$n=0;
	while (($data = fgetcsv($e, 1000, ";")) !== FALSE) {
		if($n) $csv[] = (object)array(
			$data0[0]=&gt;$data[0],
			$data0[1]=&gt;$data[1],
			$data0[2]=&gt;$data[2]
		);
		else {
			$data0=$data;
			$n=1;
		}
	}
	fclose($e);
}
echo "&lt;pre&gt;";
var_dump($csv);
echo "&lt;/pre&gt;";
echo json_encode($csv);


Amicalement,


Merci beaucoup pour ta proposition!
Ca marche super bien, c'est exactement ce que je cherchais à faire (;
Bonne journée à toi, je mets le sujet en résolu
Modérateur
cette class est très vieille mais fonctionne très bien. Je l'ai réutilisé pour un projet il y a quelques temps qui tourne. Après la syntaxe, est plutôt vieille (php 5.x) :


<?php
class Utilities {

    /**
     * Returns a string with all spaces converted to underscores (by default), accented
     * characters converted to non-accented characters, and non word characters removed.
     *
     * @param string $string the string you want to slug
     * @param string $replacement will replace keys in map
     * @return string
     */
    public static function slug($text, $replacement = '_') {
        $text = preg_replace('~[^\pL\d]+~u', $replacement, $text);

        $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);

        $text = strtolower(trim(preg_replace('~-+~', '-', preg_replace('~[^-\w]+~', '', $text)), '-'));

        if (empty($text)) {
            return 'n-a';
        }

        return $text;
    }
}





<?php
   class CSVReader{
    const OPEN_FILE_MODE = "r";

    // Must be greater than the longest line (in characters) to be found in the CSV file (allowing for trailing line-end characters). Otherwise the line is split in chunks of length characters, unless the split would occur inside an enclosure.
    const LENGTH = 0;

    //path to csv file
    private $file = null;

    // ressource csv file
    private $ressource = null;

    // The optional delimiter parameter sets the field delimiter (one character only).
    private $separator = null;

    // The optional enclosure parameter sets the field enclosure character (one character only).
    private $enclosure = null;

    // The optional escape parameter sets the escape character (at most one character). An empty string ("") disables the proprietary escape mechanism.
    private $escape = null;

    //index
    private $first_record = null;

    //données sous forme de tableau associatif
    private $data = null;

    private static $instance = null;


    private function __construct($separator, $enclosure, $escape){
        if(!is_string($separator)) throw new Exception(sprintf('the separator (%s%s) must be string', __CLASS__, __METHOD__));
        if(!is_string($enclosure)) throw new Exception(sprintf('the enclosure (%s%s) must be string', __CLASS__, __METHOD__));
        if(!is_string($escape)) throw new Exception(sprintf('the escape (%s%s) must be string', __CLASS__, __METHOD__));
        $this->separator = $separator;
        $this->enclosure = $enclosure;
        $this->escape = $escape;


    }


    public static function initialize($separator = ",", $enclosure = '"', $escape = "\\"){
        if(is_null(self::$instance)) {
            self::$instance = new CSVReader($separator, $enclosure, $escape);
        }

        return self::$instance;
    }


    public function set_file($value, $first_record = 0, $offset = null){
        // if(!file_exists($value) || trim(strtolower(@end(explode('.', $value)))) !== 'csv')
        //     throw new Exception(sprintf("can't access or the value (%s) must be a csv file", $value));
        if(!is_integer($first_record))
            throw new Exception(sprintf("first record (%s) must be an integer", $first_record));
        if(!is_integer($offset) && !is_null($offset))
            throw new Exception(sprintf("offset (%s) must be an integer", $offset));

        $this->file = $value;
        $this->get_data($first_record, $offset);

        return $this;

    }


    public function set_separator($value){
        if(!is_string($value))
            throw new Exception(sprintf('this attribute (%s) must be string (%s)', 'separator', $value));

        $this->separator = $value;
        return $this;
    }


    public function set_enclosure($value){
        if(!is_string($value))
            throw new Exception(sprintf('this attribute (%s) must be string (%s)', 'enclosure', $value));

        $this->enclosure = $value;
        return $this;
    }


    public function set_escape($value){
        if(!is_string($value))
            throw new Exception(sprintf('this attribute (%s) must be string (%s)', 'escape', $value));

        $this->escape = $value;
        return $this;
    }


    public function __get($attribute){
        switch ($attribute) {
            case 'fields':
            case 'data':
                return $this->$attribute;

            default:
                throw new Exception(sprintf("this attribute (%s) doesn't exist or you can't access it", $attribute));
                break;
        }
    }


    private function get_data($first_record, $offset){
        $raw_data = $this->get_raw_data();

        if(empty($raw_data)){
            throw new Exception(sprintf("can't get data from file %s", $this->file));
        }
        $fields = array_shift($raw_data);

        $this->set_fields($fields);
        $slugifyFields = $this->slugify($this->fields);
        $data = [];
        for($index = 0, $len = count($raw_data); $index < $len; $index++){
            if($row = @array_combine($slugifyFields, $raw_data[$index])){
                $data[] = json_decode (json_encode($row), false);
            }else{
                throw new Exception(sprintf("integrity of row is not correct : %s", $index));
            }
        }

        if(!fclose($this->ressource)){
            throw new Exception(sprintf("can't close the file %s", $this->file));
        }

        $this->data = array_slice($data, $first_record, !is_null($offset)? $offset : count($data));

        return $this;
    }


    private function get_raw_data(){
        $records = [];
        if(!($this->ressource = fopen($this->file,self::OPEN_FILE_MODE))){
            throw new Exception(sprintf("can't open file %s", $this->file));
        }
        while($row = fgetcsv($this->ressource,self::LENGTH,$this->separator, $this->enclosure, $this->escape)){
            $records[] = $row;
        }
        return $records;
    }

    private function set_fields($array){
        $this->fields = $array;
    }


    private function slugify($array){
        return array_map(function($item){
            return strtolower(Utilities::slug($item));
        }, $array);
    }
}



<?php 
    $csv = CSVReader::initialize();
    $rows =  $csv->set_separator(';')->set_file('name.csv');
    $data = $rows->data;
    $fields = $rows->fields;
?>


Si tu veux le passer en array::assoc, regarde de ce côté là :

$slugifyFields = $this->slugify($this->fields);
        $data = [];
        for($index = 0, $len = count($raw_data); $index < $len; $index++){
            if($row = @array_combine($slugifyFields, $raw_data[$index])){
                $data[] = json_decode (json_encode($row), false);
            }else{
                throw new Exception(sprintf("integrity of row is not correct : %s", $index));
            }
        }


Modifié par niuxe (14 Mar 2021 - 16:27)