One to many php pdo

Résolu/Fermé
anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022 - Modifié le 17 mai 2022 à 14:44
anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022 - 12 juin 2022 à 19:14
Bonjour,

Salut tout le monde, alors voila j'ai un fichier csv et je doit insérer les données dans une bdd créer à partir d'un MCD

CSV :


MCD :



Voilà mon code pour l'instant :

<?php

error_reporting(E_ALL);
ini_set("display_errors", 1);

include 'bdd.php';

$tab_color = [];
$tab_size = [];
$tab_category = [];
$tab_product = [];
$row = 1;
$tab_all = [];

if (($handle = fopen("chaussures.csv", "r")) !== FALSE) {

    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {

        if($row == 1){
            $row++; 
            continue;
        }

        $num = count($data);
        $row++;
       
        array_push($tab_color, $data[3]);
        array_push($tab_size, $data[2]);
        array_push($tab_category, $data[1]);
        array_push($tab_product, $data[0]);

        array_push($tab_all, $data);
        
    }

    fclose($handle);
    
}

echo print_r($tab_product);

$tab_color = array_unique($tab_color);
$tab_size = array_unique($tab_size);
$tab_category = array_unique($tab_category);

for ($i=0; $i < count($tab_color); $i++) { 
    $sql = "INSERT INTO colors(color) VALUES(:color)";
    $sth = $bdd->prepare($sql);
    $sth->bindParam('color', $tab_color[$i], PDO::PARAM_STR);
    $sth->execute();
}

for ($i=0; $i < count($tab_size); $i++) { 
    $sql = "INSERT INTO size(value) VALUES(:size)";
    $sth = $bdd->prepare($sql);
    $sth->bindParam('size', $tab_size[$i], PDO::PARAM_STR);
    $sth->execute();
}

for ($i=0; $i < count($tab_category); $i++) { 
    $sql = "INSERT INTO categories(category) VALUES(:category)";
    $sth = $bdd->prepare($sql);
    $sth->bindParam('category', $tab_category[$i], PDO::PARAM_STR);
    $sth->execute();
}


donc j'arrive à remplir correctement mes trois table category, colors et size
en revanche pour la table products..

j'ai essayer sa :

$select_size = $bdd->query('SELECT * FROM size');
$select_category = $bdd->query('SELECT * FROM categories');
$select_color = $bdd->query('SELECT * FROM colors');

for ($i=0; $i < count($tab_product); $i++) {
    while ($val = $select_size->fetch()) {
        while ($valu = $select_category->fetch()) {
            while ($value = $select_color->fetch()) {
                $test = $bdd->prepare('INSERT INTO products(name, size_id, categories_id, colors_id) VALUES(?, ?, ?, ?)');
                $test->execute(array($tab_product[$i], $val['id'], $valu['id'], $value['id']));
            }
        }
    }
}


mais ça ne marche pas ...

Configuration: Windows / Chrome 101.0.4951.67
A voir également:

2 réponses

jordane45 Messages postés 38380 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 13 janvier 2025 4 727
Modifié le 17 mai 2022 à 18:25
Bonjour,

Déjà, commence par découper ton code en petites fonctions...
Une fonction pour ajouter une couleur en bdd, une autre pour l'ajout de catégorie .. une pour l'ajout de produit .. ça rendra ton code plus clair.

Ensuite, c'est surtout un souci d'algorithmie ton truc ...
Comment fais tu le lien entre les éléments que tu places dans tes arrays... et les données des produits ??

Il faut :

Pour chaque ligne de ton csv:

1 - Vérifier si la catégorie existe déjà dans la bdd.
Si oui.. récupérer son ID
Si non, l'insérer dans ta table et récupérer son id ( pour ça, regarde en pdo : lastInsertId )
2 - Idem pour la couleur
3 - Idem pour la taille
4 - Vérifier si le produit existe déjà en bdd
--- Si oui, ne rien faire
--- Si non.. l'ajouter en bdd

N'oublies pas de faire des TRY/CATCH à chaque requête comme je te l'ai déjà dit me semble-t'il ... et à activer la gestion des erreurs php..
Pour rappel :
https://forums.commentcamarche.net/forum/affich-37584941-php-pdo-gerer-les-erreurs




1
anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022 6
Modifié le 17 mai 2022 à 22:41
Okay j'ai fait des functions et le try/catch ainsi que la gestion des erreurs comme l'explique très bien ton article ;), merci !
Maintenant je suis toujours bloqué en fait j'ai du mal à comprendre comment ajouter les champs correspondant aux champs des 3 autres tables ...
avec ce que j'ai tenté j'ai l'impression d'être pas loin mais sa ne change pas le nom et sa boucle seulement trois fois cars il n'y as que trois données dans mes boucles while...

la je suis en train de tester quelque chose comme sa :
products($bdd, $tab_category, $tab_color, $tab_size, $tab_product);
function products($bdd, $tab_category, $tab_color, $tab_size, $tab_product){
    for ($i=0; $i < count($tab_product); $i++) {

        $select_size = $bdd->query('SELECT * FROM size');
        $select_category = $bdd->query('SELECT * FROM categories');
        $select_color = $bdd->query('SELECT * FROM colors');
    
        while ($val = $select_size->fetch()) {
            $id_size = $val['id'];
        }
    
        while ($valu = $select_category->fetch()) {
            $id_cat = $valu['id'];
        }
    
        while ($value = $select_color->fetch()) {
            $id_color = $value['id'];
        }
    
        $test = $bdd->prepare('INSERT INTO products(name, size_id, categories_id, colors_id) VALUES(?, ?, ?, ?)');
        $test->execute(array($tab_product[$i], $id_size, $id_cat, $id_color));
    
    }
}


sa m'insert bien les bons nom mais du coup sa m'insert le dernier id des autres tables ..
0
jordane45 Messages postés 38380 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 13 janvier 2025 4 727 > anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022
17 mai 2022 à 22:46
heu.. tu as fais DES fonctions ?
Je n'en vois qu'une ....

En plus.. à quoi servent tes requêtes SELECT ici dans le code que tu nous montres ???
Tu comprends le code que tu fais ???????

Je repête donc ...

- Tu boucles sur chaque ligne de ton CSV

Dans cette boucle ....
Tu lis le nom de la catégorie.... tu regardes en BDD si elle existe .. si elle n'existe pas tu la créés et en même temps tu récupères l'ID qui vient d'être ajouté ( via, comme je te l'ai déjà dit, lastInsertId en PDO )
Si elle existe... tu récupères simplement son ID.
Puis..
Tu fais la même chose pour la taille ... et pour la couleur....
Une fois que tu as gérer ces 3 valeurs de ton csv, là tu peux ajouter le produit ... ( et vu que tu auras donc les 3 id correspondants aux couleur, taille et catégorie .. tu pourras sans mal l'ajouter à ta bdd...
1
anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022 6 > jordane45 Messages postés 38380 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 13 janvier 2025
Modifié le 17 mai 2022 à 23:17
Je pensais que tu parlais des autres tables pour les functions, les selects c'était pour sélectionner les id cars je n'était pas encore en train d'utiliser le lastInsertId et non j'ai un peu de mal à comprendre c'est nouveau pour moi l'insertion d'enregistrements correspondants à un csv..

Est ce que sa donnerai quelque chose comme sa :

function recup_category($bdd, $tab_category){
    for ($i=0; $i < count($tab_category); $i++) {
        try {
            $val = $bdd->query('SELECT * FROM categories');
            $valu = $val->fetch();
            if ($tab_category === $valu['category']) {
                return $cat_id = $bdd->lastInsertId();
            }
        } catch(PDOExecption $e) {
            $bdd->rollback();
            print "Error!: " . $e->getMessage() . "</br>";
        }
    }
}


sachant que la donnée existe déjà et qu'elle est déjà créer dans ma table
0
anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022 6 > jordane45 Messages postés 38380 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 13 janvier 2025
17 mai 2022 à 23:25
qu'est ce que tu pense de quelque chose comme sa :

function recup_category($bdd, $tab_category){
    for ($i=0; $i < count($tab_category); $i++) {
        $val = $bdd->query('SELECT * FROM categories');
        $valu = $val->fetch();
        if ($tab_category === $valu['category']) {
            return $cat_id = $valu['id'];
        }
    }
}
0
anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022 6 > jordane45 Messages postés 38380 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 13 janvier 2025
17 mai 2022 à 23:30
Je pense que tu est en train de pleurer derrière ton écran je suis navré j'essaie mais comme je te l'ai dit c'est nouveau encore pour moi... il commence à se faire tard par ici je vais me coucher mais si je trouve la solution demain je manquerai pas de la donnée ici ;)

Je te remercie pour le temps que tu me consacre et je te souhaite une bonne nuit / bonne journée je sais pas quelle heure il est chez toi.
Bye
0
jordane45 Messages postés 38380 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 13 janvier 2025 4 727
Modifié le 18 mai 2022 à 00:10
pfffffffff..........
:-)
>Bref...
En gros
<?php
//affichage des erreurs PHP dans la page pour être sûr de ne rien laisser trainer...
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
  
//connexion à la BDD
require_once 'bdd.php';


/**----------------------------------------------------------
* FONCTIONS UTILES POUR MANIPULER LA BDD
*-----------------------------------------------------------*/

//Fonction permettant d'exécuter des requêtes préparées
function dbQuery($sql,$datas){
  global $bdd; 
  try{
    $prep = $bdd->prepare($sql);
    return $prep->execute($datas);
  }catch(PDOException $e){
    echo "Erreur : " . $e->getMessage();
  }
   
}

//permet de faire une requête SELECT et de retourner le premier jeu de résultat
function db_One($sql,$datas=NULL){
  $res = dbQuery($sql,$datas);
  return  $res->fetch(); 
}

//permet de faire une requête SELECT et de retourner tous les résultats
function db_All($sql,$datas=NULL){
  $res = dbQuery($sql,$datas);
  return  $res->fetchAll(); 
}

//Permet de faire une requête INSERT et de retourner l'id créé (si il est en auto-incrément bien entendu..)
function db_Insert($sql,$datas=NULL){
  global $bdd;
  $res = dbQuery($sql,$datas);
  return  $bdd->lastInsertId();  //https://www.php.net/manual/fr/pdo.lastinsertid.php
}


/**----------------------------------------------------------
* FONCTIONS pour gérer les catégories
*-----------------------------------------------------------*/
function getCategory($category){
  $sql = 'SELECT * FROM categories WHERE category =:category';
  $datas = [':category'=>$category];
  return db_One($sql,$datas);
}

function addCategory($category){
  $sql = "INSERT INTO categories (category) VALUES (:category)";
  $datas = [':category'=>$category];
  return db_Insert($sql,$datas); // retourne l'ID nouvellement créé ( à condition qu'il soit en auto-incrémenté)
}

// ... je te laisse reproduire la même chose pour les couleurs et les tailles....
//...
//...


function addProduct($product, $id_size, $id_cat, $id_color){
  $sql('INSERT INTO products(name, size_id, categories_id, colors_id) VALUES(?, ?, ?, ?)');
  $datas =array($product, $id_size, $id_cat, $id_color);
  return db_Insert($sql,$datas); // retourne l'ID nouvellement créé ( à condition qu'il soit en auto-incrémenté)  
}



// ------  DEBUT DU TRAITEMENT DU CSV ------------//
$result = []; // pour stocker le résultat des insert de produit
$row = 0;

if (($handle = fopen("chaussures.csv", "r")) !== FALSE) {
  //on boucle sur le csv ..
  while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
    $row++;
    if($row == 1){
      continue;
    }
    
    //récupération des données dans le csv
    $product = !empty($data[0]) ? trim( $data[0] ) : NULL;
    $category = !empty($data[1]) ? trim( $data[1] ) : NULL;
    $size = !empty($data[2]) ? trim( $data[2] ) : NULL;
    $couleur = !empty($data[3]) ? trim( $data[3] ) : NULL;
    
    // On gère les catégories
    $db_category = getCategory($category);
    if(empty($db_category)){
      //on ajoute la catégorie et on récupère son ID
      $id_cat = addCategory($category); 
    }else{
       $id_cat = $db_category['id'];
    }
   

    // ... je te laisse reproduire la même chose pour les couleurs et les tailles....
    //...
    //...

    $result[$product] = addProduct($product, $id_size, $id_cat, $id_color);
    
  }
  
  fclose($handle);
  
  var_dump($result);
}




1
anthonyr_25 Messages postés 165 Date d'inscription mercredi 5 janvier 2022 Statut Membre Dernière intervention 6 juillet 2022 6
12 juin 2022 à 19:14
merci j'ai mis du temps à répondre mais sa à marcher !!
0