PDO : INSERT INTO [Résolu/Fermé]

Signaler
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
-
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
-
Bonsoir à tous,

Pendant quelques jours, je suis resté silencieux pour réétudier les tutos et autres éditions sur le PHP et plus encore le PDO ; j'ai remis en forme, imprimé, lu et relu ; certes, j'ai recadré un certain nombre de renseignements, mais, au vu de mes résultats, ce soir, je mords la poussière avec déception !
Heureusement que je connais la puissance de votre appui pour me remettre sur le bon chemin et ne pas jeter l'éponge
.

J'ai une page qui fonctionne et fait la même chose que celle sur laquelle je bute mais qui elle... est d'avant donc d'une bonne semaine, avant que je ne décide de basculer en PDO !

Depuis, j'ai tenté d'ingurgiter PDO, les contrôles de diverses natures mais n'ai pas voulu (encore) aller jusqu'à une fonction prepare ! Je me suis donc limité à un $PDO->exec ('INSERT INTO
Pour autant, j'ai intégré quelques $pdo->quote( pour des zones dont j'avais vérifié la présence voire supprimé les blancs devant et derrière mais sans plus.
J'ai vu et revu l'instruction 96 sur laquelle je bute mais contrôlant les parités (dans l'ordre des parenthèses) ,...

J'ai limité mes chaines au minimum soit un champ mais rien n'y fait :
Parse error: syntax error, unexpected T_VARIABLE in /web/utlsudgoelo/www/pgUTL/traitformul.php on line 95 soit à quelques lignes de la fin l'instruction :

$pdo->exec('INSERT INTO adh (anais, civil, nomadh, prenom, ad1, ad2, cpost, ville, tfixe, tmob, admail, MaJ)
VALUES ('.$anais'.'$civil'.$pdo->quote($nomadh).$pdo->quote($prenom).$pdo->quote($ad1).$pdo->quote($ad2).'$cpost'.$pdo->quote($ville).$pdo->quote($tfixe).$pdo->quote($tmob).$pdo->quote($admail).'CURDATE()')');



Malgré toutes ces recherches, je bute sur un parse error
Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in /web/utlsudgoelo/www/pgUTL/traitformul.php on line 95

Peut-être est-ce quelque chose d'évident et choquant pour un spécialiste de ne pas être découvert vu toute la doc qui s'accumule sur ces thèmes ! Je mets le code de la page ci-dessous :
<?php 
// Parametres mysql PDO     RJL2716           /* <?php  
include("ConnectBDutl"); /* ?> */ 
 echo "entrée dans traitformul.php";?><br /><?php   
 echo $serveur='sql1';?><br /><?php    // serveur mysql 
 echo $bdname='utlsudgoelo';?><br /><?php       // nom de la base 
 /* $dsn = 'mysql:host=sql1;dbname=$bdname'; */ 
 $dsn = 'mysql:host=sql1;dbname=utlsudgoelo'; 
 $utilisateur='utlsudgoelo';      // nom d'utilisateur  
 $motDePasse='********';       // mot de passe 
 echo $dsn;?><br /><?php 

// Connexion à MySQL 
 try 
  { 
  $arrExtraParam= array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8", 
         PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); 
  $connexion = new PDO( $dsn, $utilisateur, $motDePasse, $arrExtraParam ); 
//  $connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); RJL2716 
  } 
 catch (Exception $er ) 
  { 
  echo "Connexion à la Base de données MySQL impossible : ", $er->getMessage(); 
  die(); 
  } 

// controle valeurs transmises 
// sélection de la base de données 
// mysql_select_db(DB_DATABASE, $connect) or die (mysql_error()); 
// mysql_query("SET NAMES utf8");  
// à ajouter au début du script au cas où magic_quotes soit à ON  
 if (get_magic_quotes_gpc())  
  {  
  $_POST = array_map('stripslashes', $_POST);  
  }  

//  echo "($_POST)"; echo ($_POST); 
 $msg_erreur = "Erreur. Les champs suivants doivent être correctement remplis: 
<br/><br/>"; 
 $msg_ok = "Votre demande a bien été prise en compte."; 
 $message = $msg_erreur; 
// vérification des champs 
// print_r($_POST);  echo "\n";  // contrôle données traitées 
 $anais =($_POST['anais']); 
 if (empty($anais))  
  $message .= "Votre année de naissance<br/>"; 
 $ancour = date("Y"); 
 if (!is_int($anais)) 
  $message  .= "Année naissance non conforme<br/>"; 
 else if  (($anais <$ancour - 100) or 
    ($anais > $ancour -25))  
    $message .= "Année naissance incorrecte<br/>"; 
 if (empty($_POST['civil']))  
  $message .= "Votre civilité<br/>";  
 if (empty($_POST['nomadh']))  
  $message .= "Votre nom<br/>"; 
 if (empty($_POST['prenom']))  
  $message .= "Votre prénom<br/>"; 
 if (empty($_POST['ad1']))  
  $message .= "Votre adresse<br/>";  
 $cpost =($_POST['cpost']); 
 if (!is_int($cpost)) 
  $message  .= "Code postal non conforme<br/>"; 
 else if  (($cpost <1000) or 
     ($cpost > 95999)) 
    $message .= "Code postal erroné<br/>"; 
 if (empty($_POST['ville']))  
  $message .= "Votre ville<br/>"; 
// On va vérifier l'email ... 
 $admail=mysql_real_escape_string(trim($_POST['admail'])); 
 If ((empty ($admail)) 
 or (!preg_match("#^[a-z0-9._-]{1,}@[a-z0-9._-]{2,}\.[a-z]{2,4}$#",$admail))) 
   $message .= "Code e-mail invalide<br/>";  //    /*  adresse mail incorrecte */ 
 $tfixe=mysql_real_escape_string(trim($_POST['tfixe']));  
 $tmob=mysql_real_escape_string(trim($_POST['tmob']));  
 If  ((empty ($tfixe)) 
 or  (!preg_match("#^0[1-68][0-9]{8}$#",$tfixe))) 
   $message .= "N° Téléphone fixe invalide<br/>"; 
 If ((empty ($tmob))  
 or (!preg_match("#^0[1-68][0-9]{8}$#",$tmob)))   
   $message .= "N° Téléphone mobile invalide<br/>"; 
 $nomadh=mysql_real_escape_string(trim($_POST['nomadh'])); 
 $prenom=mysql_real_escape_string(trim($_POST['prenom'])); 
 $ad1=mysql_real_escape_string(trim($_POST['ad1']));  
 $ad2=mysql_real_escape_string(trim($_POST['ad2']));  
 $civil=mysql_real_escape_string(trim($_POST['civil']));  
 $ville=mysql_real_escape_string(trim($_POST['ville'])); 
// si un champ est vide, afficher le message d erreur 
 if (strlen($message) > strlen($msg_erreur)) { 
  $message .= "<br />Revenir par la flèche à la page précédente et corriger"; 
  echo $message; exit;}  
// sinon c est ok  
 $msg_ok .= "<br /> <br />Revenir par la flèche à la page précédente et cliquer sur le menu désiré"; 
  
 $pdo->exec('INSERT INTO adh (anais, civil, nomadh, prenom, ad1, ad2, cpost, ville, tfixe, tmob, admail, MaJ)    
   VALUES ('.$anais'.'$civil'.$pdo->quote($nomadh).$pdo->quote($prenom).$pdo->quote($ad1).$pdo->quote($ad2).'$cpost'.$pdo->quote($ville).$pdo->quote($tfixe).$pdo->quote($tmob).$pdo->quote($admail).'CURDATE()')'); 
 $res = mysql_query($sql); 

 if ($res)  
  { 
  echo $msg_ok; 
  } 
 else  
  { 
  echo mysql_error(); 
  } 
   
?>

Alors toutes mes excuses mais plus encore mes remerciements pour ceux qui auront la gentillesse et la générosité de se pencher sur ce problème.
@bientôt RJL1717




6 réponses

Messages postés
1081
Date d'inscription
mardi 30 septembre 2008
Statut
Membre
Dernière intervention
26 janvier 2019
102
salut,

je passe au hasard ici et :

('.$anais'.'$civil'. <- y'a pas un blem dans les points ?
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
48
Bonsoir jiantox,
Merci de ta réponse rapide... même si elle est due au hasard ...!
Problème de points, ici, je ne pense pas... encore que mais ça va permettre à un autre internaute de confirmer ou non : j'ai revu le tuto sur lequel j'ai travaillé et ça me paraissait conforme !
Malgré tout, tu as sans doute raison car il y a aussi des virgules...
Je réétudies et refais un essai !
En tout cas, merci de ce tuyau car, entre les zones numériques, celles que je traite ou non en $pdo->quote je m'y perd si je n'ai pas une concentration maximum.
Bonne fin de soirée RJL1717
Messages postés
1081
Date d'inscription
mardi 30 septembre 2008
Statut
Membre
Dernière intervention
26 janvier 2019
102
pas de quoi, au passage ta PDO est bisard

$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$bdd = new PDO('mysql:host=tonsql;dbname=tabase', 'ton id', 'ton mdp', $pdo_options);

ensuite pour les requetes je fais comme suit :

$machin = 'ce que tu veux chercher par exemple';
$requette = $bdd->prepare("SELECT * FROM base WHERE machin = ? ......... ");
$requette->execute(array($machin));
$result = $requette->fetch();

du coup $result ressort ce que je veut ( idem pour les update,insert,delete ... ) =)

EDIT : plus d'infos: https://openclassrooms.com/fr/courses/918836-concevez-votre-site-web-avec-php-et-mysql/914508-ecrivez-des-donnees
Messages postés
1054
Date d'inscription
samedi 14 mars 2009
Statut
Membre
Dernière intervention
23 octobre 2013
145
En effet, les requêtes préparées ! Voire même utiliser beginTransaction, commit et le rollBack en cas d'erreur, si le SGBD le supporte...
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
48
Bonsoir à tous,

Avec l'appui de jiantox, que je remercie au passage pour ses dernières informations, j'ai progressé et bute maintenant sur le coeur du problème PDO :

Fatal error: Call to a member function exec() on a non-object in /web/utlsudgoelo/www/pgUTL/traitformul.php on line 97
laquelle contient :

$pdo->exec('INSERT INTO adh (anais, civil, nomadh, prenom, ad1, ad2, cpost, ville, tfixe, tmob, admail, MaJ)
VALUES ('.$anais.','.$civil.','.$pdo->quote($nomadh).','.$pdo->quote($prenom).','.$pdo->quote($ad1).','.$pdo->quote($ad2).','.$cpost.','.$pdo->quote($ville).','.$pdo->quote($tfixe).','.$pdo->quote($tmob).','.$pdo->quote($admail).','.CURDATE().')');

Pour moi, je crois être conforme au tuto de Guillaume "pdo-comprendre-et-corriger-les-erreurs-les-plus-frequentes" où je trouve :
$pdo->exec('INSERT INTO livre_or(pseudo, message, date_post) VALUES('. $pdo->quote($_POST['pseudo']) .', '. $pdo->quote($_POST['message']) .', NOW())');

Dans l'immédiat, il ne s'agit que d'une requête de création à partir d'éléments venant d'un formilaire.
Merci de vos indications pour corriger cette instruction

@bientôt RJL2717

Bonjour

Si tu as l'erreur Call to a member function exec() on a non-object sur l'instruction $pdo->exec('INSERT INTO... cela signifie que $pdo n'est pas un objet.
Si j'en crois ton premier script, ton instance PDO ne s'appelle pas $pdo, mais $connexion.Si tu as suivi l'exemple de jiantox, elle s'appelle $bdd.
Si tu es sûr (mais es-tu sûr ?) que tu l'as appelé $pdo, alors c'est que la connexion a échoué.

D'autre part, si un tuto t'a conseillé d'utiliser $pdo->quote, efface vite le lien et oublie-le. Le manuel de référence PHP déconseille très fortement l'utilisation de $pdo->quote, qui fait perdre tout l'intérêt du PDO. Il FAUT utiliser des requêtes préparées , avec des ? ou des paramètres nommés dans la requête, et passer un array pour l'exécution comme dans l'exemple de jianto. Pour reprendre ton exemple ci-dessus :

$stmt = $pdo->prepare('INSERT INTO adh (anais, civil, nomadh, prenom, ad1, ad2, cpost, ville, tfixe, tmob, admail, MaJ)
VALUES (?,?,?,?,?,?,?,?,?,?,?,CURDATE());

$stmt->execute(array($anais, $civil, $nomadh, $prenom, $ad1, $ad2, $cpost, $ville, $tfixe, $tmob, $admail)); 


Enfin, tous tes mysql_real_escape_string n'ont RIEN DU TOUT à faire dans un script où tu utilises PDO. C'est même étrange que ça ne te provoque pas d'erreur.
Messages postés
1054
Date d'inscription
samedi 14 mars 2009
Statut
Membre
Dernière intervention
23 octobre 2013
145
Je ne vois pas pourquoi ça provoquerait une erreur, mais les fonctions mysql étant dépréciées...
De plus, il serait mieux d'éviter les "?" à la mode mysqli et donner des noms plus explicites aux données afin de garder une certaine lisibilité du code
Utilisateur anonyme
Ça ne devrait pas marcher car mysql_real_escape_string est lié à une connexion par les fonctions de la famille mysql_. Je viens de refaire l'essai à l'instant pour m'en assurer, bien que cela semble logique : malgré une connexion PDO qui fonctionne très bien, l'appel à mysql_real_escape_string provoque une erreur :
mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'ODBC'@'localhost' (using password: NO) in ....php on line 345
Et indépendamment de cette erreur à l'appel, cela dénaturerait les informations enregistrées car les caractères spéciaux seraient échappés deux fois.

Par contre, tout à fait d'accord pour l'utilisation de noms plus explicites au données, j'en parlais dans ma réponse, mais j'ai mis des ? par pure fainéantise :o
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
48
J'ai pensé que les ? participaient à une meilleure sécurité que le nom des variables car, sinon, je suis moi-même plus favorable à nommer les zones !
Dans l'immédiat, j'essaie de transformer les enseignements que j'ai reçu pour une nouvelle requête préparée, cette fois en sélection.
@+ RJL2719
Utilisateur anonyme
Les ? ou le nommage des zones ne changent absolument rien à la sécurité par eux-mêmes. À ce point de vue, je crois qu'ils sont équivalents entre eux, et équivalents aussi à l'utilisation systématique de mysql_real_escape_string avec l'ancienne interface.
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
48
Bonsoir,
OK, je l'ai pris en compte et utilise au maximum les noms au lieu des ?
@+ RJL2719
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
48
Bonsoir à tous les 3 (Autumn'Tears, jiantox et bien sûr le père) qui avez participé à ces échanges.

Un grand coup de chapeau pour les conseils et propositions que vous m'avez prodigués car, malgré des erreurs multiples, les enregistrements sont contrôlés et s'enregistrent correctement, sachant qu'à chaque stade, j'essaie d'améliorer en respectant les conseils communiqués. A propos des remarque j'ai bien aimé celle ci : "Si tu es sûr (mais es-tu sûr ?) que tu l'as appelé $pdo" et, c'est vrai, je faisais mal le lien d'autant que PDO est souvent employé en préfixe de divers termes (mea culpa... comme d'habitude !).

Un détail toutefois, dans cette même page, les messages sortent parfois en illisible (pb d'encodage) et, à mes yeux se rétablissent seuls !!
Ainsi j'obtiens "Enregistrement réussi" ou des caractères non udf8
Donc, un vrai merci ... et sans doute @ bientôt pour d'autres pages que peu à peu (très très doucement) je trouve moins angoissantes à aborder !
RJL1718


Si tu es sûr (mais es-tu sûr ?) que tu l'as appelé $pdo,
Messages postés
1054
Date d'inscription
samedi 14 mars 2009
Statut
Membre
Dernière intervention
23 octobre 2013
145
En parlant d'encodage, tes champs en base de données devraient être en utf8_unicode_bin.
Et lorsque tu instancies PDO :
$pdo = new PDO($connection, $user, $pwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
Avec ça, tu te connectes à la base en UTF-8.
Et pour l'affichage sur tes pages :
en HTML : <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
en PHP : header('Content-type: text/html; charset=UTF-8');

Ça devrait résoudre tes problèmes.
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
48
Merci des détails,
J'avais des interrogations car j'avais lu (peut-être mal) que utf8 était sur 3 octets et UTF-8 sur 4 mais en tout cas une différence entre utf8 et UTF-8 !
En HTML, j'ai systématiquement <meta charset="utf8">
Je me suis rendu compte que pour les modules strictement en PHP, je n'avais pas nécessairement d'include de HTML et de ce fait traitait mal le problème ; ceci n'expliquait pas que ces derniers soirs, j'ai parfois eu debonnes éditions puis à un autre moment le même problème et message (à mes yeux) avec des caractères en encodage incorrect !
Je vais reprendre le problème posément demain à travers les différents modules d'autant qu'il faut que je creuse "header('Content-type: text/html; charset=UTF-8'); " instruction que je ne connaissait pas.
@demain RJL2720
Messages postés
1054
Date d'inscription
samedi 14 mars 2009
Statut
Membre
Dernière intervention
23 octobre 2013
145
Non, aucune différence entre utf8 et utf-8 c'est le même encodage.
C'est uniquement les caractères qu'il contient qui peuvent être stockés sur 2 à 4 octets
Messages postés
543
Date d'inscription
mardi 16 mars 2004
Statut
Membre
Dernière intervention
25 mai 2019
48
Merci de cette indication ce n'aurait été qu'une histoire de majuscule ou minuscule, j'y aurai attaché moins d'importance mais le tiret me gênait plus car je trouvais utf8 ou UTF-8 !
Merci de l'indication. RJL2720