(double) probleme pour inserer donnes dans bdd

Résolu
bonjour

j'ai retouche un code pour inserer un .csv dans du sql mais quand je tente de les rentrer dans la bdd j'ai des erreurs incomprehensibles

j'ai essayé par le module d'enregistrement #1 ( voir code ) mais j'ai cette erreur :

( données sensibles remplacées par ....... )


Erreur mise à jour table : You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '$the_big_array[] INTO TABLE produits FIELDS TERMINATED BY ';' ENCLOSED BY...' at line 1

j'ai donc essayé la module d'enregistrement #2

mais la aussi j'ai un message d'erreur :


Erreur fatale : Uncaught TypeError : mysqli_query() : L'argument #1 ($mysql) doit être de type mysqli, PDO donné dans /home/u320889525/domains/.........../public_html/..........php:24 Stack trace : # 0 /home/u320889525/domains/......../public_html/..........php(24): mysqli_query() #1 {main} jeté dans /home/u320889525/domains/......../public_html/i.......... php à la ligne 24

je n'arrive pas a determiner le nom des variables dans le array

par contre lorsque je désactive les modules d'enregistrement , j'ai un retour de tableau correct



array(4) {
[0]=>
array(3) {
[0]=>
string(6) "ggg"
[1]=>
string(3) "ttt"
[2]=>
string(2) "54"
}
[1]=>
array(3) {
[0]=>
string(4) "bbbb"
[1]=>
string(3) "fff"
[2]=>
string(2) "21"
}
[2]=>
array(3) {
[0]=>
string(3) "ggg"
[1]=>
string(3) "kkk"
[2]=>
string(2) "78"
}
[3]=>
array(3) {
[0]=>
string(3) "jjj"
[1]=>
string(3) "sss"
[2]=>
string(2) "44"
}
}


voici le code :

<?php
$filename = 'amazon-fours.csv';

// The nested array to hold all the arrays
$the_big_array = [];

// Open the file for reading
if (($h = fopen("{$filename}", "r")) !== FALSE)
{
// Each line in the file is converted into an individual array that we call $data
// The items of the array are comma separated
while (($data = fgetcsv($h, 0, ";")) !== FALSE)
{
// Each individual array is being pushed into the nested array
$the_big_array[] = $data;
}
}

include("db_connect.php");

// module d'enregistrement #1

mysqli_query($conn,'LOAD DATA LOCAL INFILE \'amazon-fours.csv\' INTO TABLE produits
FIELDS TERMINATED BY \';\'
ENCLOSED BY \'"\'
LINES TERMINATED BY \'\n\' ')
or die("Erreur mise à jour table : ".mysqli_error($conn));



/*
// module d'enregistrement #2

$data = [
'name' => $the_big_array[1],
'description' => $the_big_array[2],
'prix' => $the_big_array[3]
];
$sql = "INSERT INTO file VALUES (NULL,:name,:description,:prix)";
$stmt= $conn->prepare($sql);
$stmt->execute($data);


*// afficher le codeecho "<pre>";var_dump($the_big_array);echo "</pre>";?><bold>db_connect.php</bold><?php$server = "localhost";$username = "*******";$password = "*******";$db = "*********";$conn = mysqli_connect($server, $username, $password, $db);session_start();$_SESSION[`connect`] = $conn ;?>



EDIT : Correction des balises de code ( ajout du LANGAGE )



merci de m'aider je suis debutant en php et j'ai beau chercher une solution je trouve pas

j'ai verifié db_connect la connection est bonne

version php 8.0

15 réponses

Résumé de la discussion

Le fil porte sur des difficultés d'importer un fichier CSV dans une base MariaDB, avec des erreurs SQL et des messages liés à mysqli et PDO qui bloquent l’exécution. Plusieurs intervenants constatent une incohérence entre mysqli et PDO et recommandent de standardiser le code autour d’un seul driver, tout en corrigeant la syntaxe des requêtes et des imports. Des cas concrets évoquent des erreurs près des commandes LOAD DATA LOCAL INFILE et des problèmes de syntaxe liés à des placeholders ou à l’emploi de variables. En dernier ressort, certaines réponses orientent vers PDO avec une gestion d’erreurs adaptée et soulignent l’importance de vérifier la définition des champs (prix décimal, noms de colonnes) pour éviter des incompatibilités.

Bobot (l’IA à votre service)
  1. Modérateur
    Bonjour,

    Vu les messages d'erreur, il faudrait déjà savoir ce que contient le fichier include("db_connect.php")
    0
    1. contenu db_connect.php

      <?php
      $conn = mysqli_connect("localhost", "..............", "...............", "....................")
      or die("Impossible de se connecter : " . mysqli_error());
      echo 'Connexion réussie';

      ?>


      le retour est positif j'ai bien le echo qui s'affiche
      0
      1. Contributeur Ambassadeur
        bonjour,
        moi je modifierais le texte sur la ligne
        echo
        du fichier db_connect.php, pour m'assurer que c'est bien le fichier utilisé.
        0
    2. Modérateur
      Tu devrais également remplacer le mot include par require_once
      Ça permettrait de s'assurer que ton fichier est bien trouvé et correctement chargé.

      0
      1. la connection se fait bien j'ai le echo ' connection reussie' qui s'affiche

        de plus je l'ai teste en creant une erreur, le die s'applique et j'ai bien le message d'erreur ( sans le echo)
        0
        1. Modérateur
          Le problème c'est que : le message d'erreur 1 ne correspond pas au code présenté..

          Et le code du module 2 n'est pas du mysqli mais du pdo ...

          Alors, pour le module 1... Vire le code qui se trouve avant (la création du big array...) Et teste le à nouveau.
          Dis nous si tu as toujours le même message (et montres nous le code modifié)
          0
          1. tu pouurais etre plus precise stp

            je debute

            merci
            0
            1. Modérateur
              Plus prescis ??
              Tu gardes les lignes 19 à 28 uniquement... Et tu testes...
              0
            2. Modérateur
              @jordane45Éventuellement, inspire toi de ce code
              $sql = 'LOAD DATA LOCAL INFILE \'amazon-fours.csv\' INTO TABLE produits
              FIELDS TERMINATED BY \';\'
              ENCLOSED BY \'"\'
              LINES TERMINATED BY \'\n\' ;';
              
              
              $result = mysqli_query($conn, $sql);
              
              if ($result) {
                $message = "The data was successfully added!";
              } else {
                $message = "error: ";
                $message .= mysqli_error($conn); 
              };
              
              echo $message;
              
              
              
              0
          2. j'ai teste en mettant des foreach


            require_once("db_connect.php");
            foreach ( $the_big_array as $ligne) {
            foreach ( $ligne as $value) {
            $data_ = [
            'name' => $value,
            'description' => $value,
            'price' => $value,
            ];
            $sql = "INSERT INTO produits (name,description,price) VALUES (:name, :description, :price)";
            $stmt= $conn->prepare($sql);
            $stmt->execute($data_);

            echo'<br/>value <br/>';
            echo $value;

            } //fin foreach
            } //fin foreach
            } //fin if isset

            echo '<br/>sql <br/>';
            echo $sql;


            ce qui donne en retour :

            Fatal error: Uncaught Error: Call to a member function execute() on bool in /home/u320889525/domains/............../public_html/..................php:33 Stack trace: #0 {main} thrown in /home/u320889525/domains/.........../public_html/.............php on line 33
            ( $stmt->execute($data_); )

            si je desactive cette ligne j'ai ceci en echo :

            value

            toutes les values ressortent

            sql
            INSERT INTO produits (name,description,price) VALUES (:name, :description, :price)

            ce qui prouve que le problème vient du insert
            0
            1. Modérateur
              Là tu es reparti sur le "second" code .... code qui utilise, comme je te l'ai déjà indiqué ... du PDO ....
              Hors... toi tu as ouvert ta connexion en mysqli ....
              Alors si tu veux utiliser ce code.. il te faut modifier le code de ton fichier db_connect.php pour le faire en PDO
              Exemple ici : https://forums.commentcamarche.net/forum/affich-37584941-php-pdo-gerer-les-erreurs
              0
          3. jordane45
            je n'ai malheureusement pas le choix vu que LOAD DATA n'est pas accepte par MariaDB

            du coup j'ai changé db_connect en PDO

            <?php
            try {
            $user = '....................';
            $pass = '...................';
            $conn = new PDO('mysql:host=localhost;dbname=..............', $user, $pass);
            } catch (PDOException $e) {
            echo 'Échec lors de la connexion : ' . $e->getMessage();
            }
            echo 'Connexion réussie';
            ?

            et j'ai en retour :

            Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in /home/u320889525/domains/best-products.fr/public_html/importcsv.php:27 Stack trace: #0 /home/u320889525/domains/best-products.fr/public_html/importcsv.php(27): PDOStatement->execute() #1 {main} thrown in /home/u320889525/domains/best-products.fr/public_html/importcsv.php on line 27

            (toujours le $stmt->execute($data_); ) et la connection se fait bien (Connexion réussie)
            0
            1. Modérateur

              je n'ai malheureusement pas le choix vu que LOAD DATA n'est pas accepte par MariaDB

              Tu n'as visiblement pas été voir le lien que je t'ai donné ...... il est normalement possible d'activer cette option.


              Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in /home/u320889525/domains/best-products.fr/public_html/importcsv.php:27

              Tu n'as pas appliqué les informations qui se trouvent dans le lien concernant PDO....
              Car si tu l'avais fait, tu aurais, plus du message d'erreur... l'affichage du contenu de la variable $data_ ... ce qui serait fort utile pour voir où se trouve l'erreur...
              Et, pour être sûr d'avoir le bon nombre de paramètres dans le $data_ .. il faut retirer les virgules superflues.
              Je t'invite également à préfixer les variable par ":"
               $data_ = [
                 ':name' => $value,
                 ':description' => $value,
                 ':price' => $value
                 ];
              


              PS: Encore une fois .. lorsque tu postes du code sur le forum .. tu dois utiliser les BALISES DE CODE !!! ( et y préciser le langage afin d'avoir la coloration syntaxique). Merci.
              0
            2. Modérateur
              @jordane45tu remarquera au passage que tu mets, pour tes trois champs .. une seule valeur ... celle de la variable $value .... c'est voulu ???
              0
          4. voila ou j'en suis

            j'ai essaye de tenir compte (au mieux de mes capacites) des differentes remarques glanées dans les différents forums et ce que j'en retire

            - à l'activation du module d'enregistrement 1 j'ai ce retour :

            Fatal error: Uncaught TypeError: mysqli_query(): Argument #1 ($mysql) must be of type mysqli, PDO given in /home/u320889525/domains/............../public_html/.........php:25 Stack trace: #0 /home/u320889525/domains/........../public_html/............php(25): mysqli_query() #1 {main} thrown in /home/u320889525/domains/................./public_html/...........php on line 25

            qui correspond a la ligne :

            " mysqli_query($conn,'LOAD DATA LOCAL INFILE \'amazon-fours.csv\' INTO TABLE produits ";

            si je desactive cette ligne j'ai ce retour :

            Parse error: syntax error, unexpected identifier "TERMINATED" in /home/u320889525/domains/.........../public_html/............php on line 27

            - à l'activation du module d'enregistrement 2 j'ai ce retour :

            Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '':name' = ?, ':description' = ?, ':price' = ?' at line 3 in /home/u320889525/domains/.............../public_html/..................php:41 Stack trace: #0 /home/u320889525/domains/................fr/public_html/.................php(41): PDO->exec() #1 {main} thrown in /home/u320889525/domains/............../public_html/............php on line 41

            qui correspond à la ligne :

            $conn->exec($sql);

            - à l'activation du module d'enregistrement 3 j'ai ce retour :

            Fatal error: Uncaught Error: Object of class PDO could not be converted to string in /home/u320889525/domains/............../public_html/...........php:49 Stack trace: #0 /home/u320889525/domains/............/public_html/...............php(49): PDOStatement->execute() #1 {main} thrown in /home/u320889525/domains/................/public_html/.............php on line 49

            qui correspond à la ligne

            $req->execute([$conn]);

            et j'ai du desactiver $price sinon j'ai cette erreur :

            Warning: Uninitialized string offset 2 in /home/u320889525/domains/........../public_html/................php on line 47

            répétée 10 fois


            <?php
            error_reporting(E_ALL);
            ini_set('display_errors', TRUE);
            ini_set('display_startup_errors', TRUE);
            $filename = 'amazon-fours.csv';

            // The nested array to hold all the arrays
            $the_big_array = [];

            // Open the file for reading
            if (($h = fopen("{$filename}", "r")) !== FALSE)
            {
            // Each line in the file is converted into an individual array that we call $data
            // The items of the array are comma separated
            include("db_connect.php");
            while (($data = fgetcsv($h, 0, ";")) !== FALSE)
            {
            // Each individual array is being pushed into the nested array
            $the_big_array[] = $data;
            foreach ($the_big_array as $table)
            {
            foreach ($table as $contenu )
            {
            /*
            // module d'enregistrement #1
            mysqli_query($conn,'LOAD DATA LOCAL INFILE \'amazon-fours.csv\' INTO TABLE produits;
            FIELDS TERMINATED BY \';\'
            ENCLOSED BY \'"\'
            LINES TERMINATED BY \'\n\' ')
            or die("Erreur mise à jour table : ".mysqli_error($conn));
            • / // module d'enregistrement #2 /* $sql = <<<SQL INSERT INTO produits SET ':name' = $contenu[0], ':description' = $contenu[1], ':price' = $contenu[2] SQL ; $conn->exec($sql); */ // module d'enregistrement #3 $name = $contenu[0]; $description = $contenu[1]; $price = $contenu[2]; $req = $conn ->prepare('INSERT INTO produits (name,description,price) VALUES ($name,$description)'); $req->execute([$conn]); } //fin foreach #2 } // fin foreach #1 } //fin while} // fin if $sh/* echo '<br/>name : <br/> '; echo $name ; echo '<br/>description : <br/>'; echo $description ; echo '<br/>price : <br/>'; echo $price ; echo '<br/>req : <br/>'; print_r($req); */ /* // afficher le code echo "<pre>"; var_dump($the_big_array); echo "</pre>"; */?>


            contenu db_connect.php :


            <?php
            error_reporting(E_ALL);
            ini_set('display_errors', TRUE);
            ini_set('display_startup_errors', TRUE);

            try
            {
            $host = 'mysql:dbname=................;host=127.0.0.1';
            $dsn = '............................."
            $user = '............................';
            $password = '...................';
            $conn = new PDO($host, $user, $password);
            // Activation des erreurs PDO
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            // mode de fetch par défaut : FETCH_ASSOC / FETCH_OBJ / FETCH_BOTH
            $conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            }
            catch(PDOException $e) {
            die('Erreur : ' . $e->getMessage());
            }
            0
            1. voila ou j'en suis

              j'ai essaye de tenir compte (au mieux de mes capacites) des differentes remarques glanées dans les différents forums et ce que j'en retire

              - à l'activation du module d'enregistrement 1 j'ai ce retour :

              Fatal error: Uncaught TypeError: mysqli_query(): Argument #1 ($mysql) must be of type mysqli, PDO given in /home/u320889525/domains/............../public_html/.........php:25 Stack trace: #0 /home/u320889525/domains/........../public_html/............php(25): mysqli_query() #1 {main} thrown in /home/u320889525/domains/................./public_html/...........php on line 25

              qui correspond a la ligne :

              " mysqli_query($conn,'LOAD DATA LOCAL INFILE \'amazon-fours.csv\' INTO TABLE produits ";

              si je desactive cette ligne j'ai ce retour :

              Parse error: syntax error, unexpected identifier "TERMINATED" in /home/u320889525/domains/.........../public_html/............php on line 27

              - à l'activation du module d'enregistrement 2 j'ai ce retour :

              Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '':name' = ?, ':description' = ?, ':price' = ?' at line 3 in /home/u320889525/domains/.............../public_html/..................php:41 Stack trace: #0 /home/u320889525/domains/................fr/public_html/.................php(41): PDO->exec() #1 {main} thrown in /home/u320889525/domains/............../public_html/............php on line 41

              qui correspond à la ligne :

              $conn->exec($sql);

              - à l'activation du module d'enregistrement 3 j'ai ce retour :

              Fatal error: Uncaught Error: Object of class PDO could not be converted to string in /home/u320889525/domains/............../public_html/...........php:49 Stack trace: #0 /home/u320889525/domains/............/public_html/...............php(49): PDOStatement->execute() #1 {main} thrown in /home/u320889525/domains/................/public_html/.............php on line 49

              qui correspond à la ligne

              $req->execute([$conn]);

              et j'ai du desactiver $price sinon j'ai cette erreur :

              Warning: Uninitialized string offset 2 in /home/u320889525/domains/........../public_html/................php on line 47

              répétée 10 fois


              <?php
              error_reporting(E_ALL);
              ini_set('display_errors', TRUE);
              ini_set('display_startup_errors', TRUE);
              $filename = 'amazon-fours.csv';

              // The nested array to hold all the arrays
              $the_big_array = [];

              // Open the file for reading
              if (($h = fopen("{$filename}", "r")) !== FALSE)
              {
              // Each line in the file is converted into an individual array that we call $data
              // The items of the array are comma separated
              include("db_connect.php");
              while (($data = fgetcsv($h, 0, ";")) !== FALSE)
              {
              // Each individual array is being pushed into the nested array
              $the_big_array[] = $data;
              foreach ($the_big_array as $table)
              {
              foreach ($table as $contenu )
              {
              /*
              // module d'enregistrement #1
              mysqli_query($conn,'LOAD DATA LOCAL INFILE \'amazon-fours.csv\' INTO TABLE produits;
              FIELDS TERMINATED BY \';\'
              ENCLOSED BY \'"\'
              LINES TERMINATED BY \'\n\' ')
              or die("Erreur mise à jour table : ".mysqli_error($conn));
              • / // module d'enregistrement #2 /* $sql = <<<SQL INSERT INTO produits SET ':name' = $contenu[0], ':description' = $contenu[1], ':price' = $contenu[2] SQL ; $conn->exec($sql); */ // module d'enregistrement #3 $name = $contenu[0]; $description = $contenu[1]; $price = $contenu[2]; $req = $conn ->prepare('INSERT INTO produits (name,description,price) VALUES ($name,$description)'); $req->execute([$conn]); } //fin foreach #2 } // fin foreach #1 } //fin while} // fin if $sh/* echo '<br/>name : <br/> '; echo $name ; echo '<br/>description : <br/>'; echo $description ; echo '<br/>price : <br/>'; echo $price ; echo '<br/>req : <br/>'; print_r($req); */ /* // afficher le code echo "<pre>"; var_dump($the_big_array); echo "</pre>"; */?>


              contenu db_connect.php :


              <?php
              error_reporting(E_ALL);
              ini_set('display_errors', TRUE);
              ini_set('display_startup_errors', TRUE);

              try
              {
              $host = 'mysql:dbname=................;host=127.0.0.1';
              $dsn = '............................."
              $user = '............................';
              $password = '...................';
              $conn = new PDO($host, $user, $password);
              // Activation des erreurs PDO
              $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
              // mode de fetch par défaut : FETCH_ASSOC / FETCH_OBJ / FETCH_BOTH
              $conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
              }
              catch(PDOException $e) {
              die('Erreur : ' . $e->getMessage());
              }
              ?>
              0
          5. Modérateur
            Faut arrêter de copier/coller tout et n'importe quoi au pif !!!

            Essaye ça
            <?php
            
            error_reporting(E_ALL);
            ini_set('display_errors', TRUE);
            ini_set('display_startup_errors', TRUE);
            
            //Connexion à la bdd ( en PDO )
            require_once("db_connect.php");
            
            $filename = 'amazon-fours.csv';
            
            // Open the file for reading
            if (($h = fopen("{$filename}", "r")) !== FALSE) {
            // Each line in the file is converted into an individual array that we call $row
            // The items of the array are comma separated
            
              while (($row = fgetcsv($h, 0, ";")) !== FALSE) {
            
                //Si l'insert ne fonctionne toujours pas, merci de décommenter les lignes ci-dessous et de nous montrer ce que ça donne
                // echo '<br>';
                // print_r($row);
                
                //données contenues dans la ligne du fichier csv  
                $datas = [
                    ':name' => !empty($row[0]) ? $row[0] : "",
                    ':description' => !empty($row[1]) ? $row[1] : "",
                    ':price' => !empty($row[2]) ? $row[2] : "",
                ];
            
                $sql = "INSERT INTO produits (name,description,price)  VALUES (:name, :description, :price)";
                //Execution de la requete
                try {
                  $requete = $conn->prepare($sql);
                  $requete->execute($datas);
                } catch (Exception $e) {
                  // en cas d'erreur :
                  echo "<br>Erreur ! " . $e->getMessage();
                  echo "<br>Les datas :<br>";
                  print_r($datas);
                  exit;
                }
              }
            }
            


            PS: A l'avenir, lorsque tu postes du code sur le forum .. tu dois préciser le LANGAGE dans les BALISES DE CODE pour avoir la coloration syntaxique.
            Explications ( à lire ENTIEREMENT !!!!!!! ) disponibles ici https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

            0
            1. merci

              j'ai pas de messages d'erreur mais seul $price apparait dans la db
              0
          6. pourtant le print_r($row) semble correct

            Array ( [0] => ggg [1] => ttt [2] => 54 ) Array ( [0] => bbbb [1] => fff [2] => 21 ) Array ( [0] => ggg [1] => kkk [2] => 78 ) Array ( [0] => jjj [1] => sss [2] => 44 )
            0
            1. Modérateur
              Comment sont définis tes champs dans la bdd ?
              Car si le prix s'enregistre... tout doit s'y mettre ...
              0
          7. # Nom Type Interclassement Attributs Null Valeur par défaut Commentaires Extra Action
            1 idPrimaire int(11) Non Aucun(e) AUTO_INCREMENT
            2 name int(255) Non Aucun(e)
            3 description int(255) Non Aucun(e)
            4 price int(255) Non Aucun(e)
            0
            1. Modérateur
              Alors toi... tu stockes des nom et des description dans des int ??
              Et le prix aussi ? tu n'auras jamais de virgules ??
              0
          8. jai remplace int par varchar cest bon

            merci
            0
            1. Modérateur
              Pas le prix j'espère...
              Le prix il faut le mettre en décimal par exemple ou en float
              0