IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Dendrite

PDO une soupe et au lit !

Note : 5 votes pour une moyenne de 4,20.
par , 20/05/2018 à 13h33 (9630 Affichages)
  1. Introduction
  2. Exemple pratique : structure de la table SQL
  3. PDO Script de connexion à la base de données
  4. Le bloc try & catch : afficher les exceptions
  5. Requête SELECT sans filtre : lister tous les enregistrements
  6. Requête SELECT avec filtre : lister les enregistrements selon critères
  7. Requête INSERT : ajouter un enregistrement
  8. Requête UPDATE : modifier un enregistrement
  9. Requête DELETE : supprimer un enregistrement
  10. Astuces et erreurs courantes
  11. Pour aller plus loin
  12. Les participants à ce billet collaboratif


1 - Introduction

PDO est une classe d’objets tout particulièrement dédiée à générer des variables PHP dynamiques (ici nous ne traiterons que des tableaux associatifs) en accédant à la base de données.
PDO permet d’utiliser des requêtes préparées, et utilisées à bon escient, les requêtes préparées permettent d’éviter une attaque de votre base par un navigateur client (injection SQL). Pour les mêmes raisons, PDO gère proprement l’échappement.

Ici, vous ne verrez QUE la technique des requêtes préparées par marqueurs anonymes. Pour utiliser la technique des requêtes préparées par marqueurs nommés, sauter au paragraphe 11 !

Et si vous vous dites : elle est bien gentille, Dendrite, mais j'en fais quoi moi après, de son tableau PHP hein ?
Ca me dit pas comment je vais le transformer en tableau HTML !
C'est par ici, la suite logique de ce billet...

De belles boucles sans frisottis

2 - Exemple pratique : structure de la table SQL

A - un identifiant unique

L'id ou identifiant, c'est une information unique pour reconnaître facilement un enregistrement. Dans la réalité, ça peut être votre numéro de Sécu, votre login sur Developpez ou le numéro de ticket que vous prenez pour faire la queue chez le boucher.
La façon la plus simple d'avoir un identifiant unique, c'est d'utiliser un chiffre et de faire ‘+1’ à chaque fois qu'une ligne est créée. Par défaut, un champ entier (INT) peut aller jusqu'à 2 147 483 647 (oui, plus de 2 milliards), ce qui veut dire qu'on peut créer une ligne toutes les secondes pendant 68 ans avant d'être à court de nombres.

B – auto-incrémentation

"auto-incrémenté", ça veut tout simplement dire qu'on va demander à la base de faire le ‘+1’ à notre place. Pas besoin de réfléchir et de chercher quel est le numéro de la dernière ligne enregistrée, ça se fait automatiquement.

C – La table contact

Si vous n’avez pas de base disponible, créez une base nommée ma_base dans votre PHPMYADMIN.
Et copiez-collez ce code SQL (dans la console SQL de PHPMYADMIN) qui vous construit et vous remplit une petite table de contacts.
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREATE TABLE IF NOT EXISTS `contact` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(100) NOT NULL,
  `prenom` varchar(100) NOT NULL,
  `mail` varchar(200) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `nom` (`nom`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
INSERT INTO `contact` (`id`, `nom`, `prenom`, `mail`) VALUES
(1, 'ACCOYER', 'Alain', 'alain.accoyer@gmail.com'),
(2, 'BRABOIS', 'Bernard', 'bbrabois@yahoo.fr'),
(3, 'CHAZAL', 'Claire', 'chaz@wanadoo.fr'),
(4, 'DENDRITE', 'Daisy', 'dendy@gmail.com'),
(5, 'CHAZAL', 'Etienne', 'chazet@gmail.com'),
(6, 'CHAZAL', 'Chantal', 'chacha@monfai.fr'),
(7, 'CHAZAL', 'Kevin', 'kevcha@noos.fr'),
(8, 'ZANZIBAR', 'Zoé', 'zanzo@orange.ocm'),
(9, 'CASERATI', 'Michel', 'michoucase@voila.fr'),
(10, 'FRIPON', 'Françoise', 'francoise.fripon@gmail.com');

3a - PDO - Script de connexion à la base de donnees

A la racine de votre site, dans le répertoire www si vous êtes sous WAMP, vous créez un fichier db_mysql.php.
Et vous collez le code suivant :
Bien sûr, vous changez ce qui a besoin de l’être dans les valeurs de votre connexion.
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
// @author : rawsrc - 2018 - Pour DVP
// on vérifie si la fonction de connexion a déjà été définie afin d'éviter de la redéfinir
if ( ! function_exists('db_connexion')) {
   function db_connexion() {
      // une fois ouverte, on renvoie toujours la même connexion
      static $pdo;
      // on vérifie si la connexion n'a pas déjà été initialisée
      if ( ! ($pdo instanceof PDO)) {
         // tentative d'ouverture de la connexion MySQL
         try {
            $pdo = new PDO('mysql:host=localhost;port=3306;dbname=ma_base;charset=utf8','root', '', [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_EMULATE_PREPARES   => false
            ]);
         } 
         catch (PDOException $e) {
            throw new InvalidArgumentException('Erreur connexion à la base de données : '.$e->getMessage());
            exit;
         }
      }
      // renvoi de la ressource : connexion à la base de données
      return $pdo;
   }
}
return db_connexion();

Comment tester votre connexion maintenant ?
En mettant juste cette ligne, sur un fichier test.php au même niveau que votre fichier db_mysql.php :
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
$db = include 'db_mysql.php';
S'il ne génère rien, c'est à dire pas d'erreur : C'est que la connexion est bonne !
Vous pouvez supprimer le fichier test.php et passer à la suite...

3b - PDO - fermer la connexion, c'est bien.
Et c'est tout simple en plus !
Là, pour les exemples, j'ouvre et je ferme à chaque requête parce que je souhaite vous livrer un code directement fonctionnel.
Mais comprenez-bien que sur un script, vous ouvrirez la connexion, vous ferez peut-être dix requêtes, de select, d'update, d'insert, toujours avec la même connexion et vous ne la fermerez qu'en fin de page.

4 – Le bloc try catch : afficher les exceptions

Maintenant, vous pouvez mettre ceci sur un nouveau fichier test.php, pour comprendre à quoi sert un bloc try and catch, et la gestion des exceptions (messages d'erreurs).
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
try{ 
   //ici vous écrivez tout votre script
   //jusqu’à la fin, s’il y a une exception, elle sera interceptée par le catch
   //on fait exprès d'écrire une bêtise ici
   //$i=0;
   echo $i;
} 
catch(Exception $e){
   //s'il y a un probleme PHP ou SQL, que ce soit un warning ou une erreur fatale, tout s'affichera ici
   print "Erreur ! " . $e->getMessage() . "<br/>";
}

5 - Requête SELECT sans filtre : lister tous les enregistrements

Testez bien la requête dans votre PHPMYADMIN d’abord !
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
SELECT *
FROM contact
ORDER BY nom, prenom;

Quand tout fonctionne, on crée une page "contact.php" que l'on positionne à la racine de notre site (toujours au même niveau que notre autre page "db_mysql.php". Elle contient ceci :
On n’a que la variable $sql à changer.
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
//pas de filtre
$sql='SELECT *
FROM contact
ORDER BY nom, prenom;';
//on initialise notre tableau PHP
$data=array();
$db = include 'db_mysql.php'; 
try{
   //la ligne qui lance la requête préparée
   $stmt = $db->prepare($sql);
   //pas de filtres donc pas de paramètres
   $stmt->execute();
   //$data est un tableau de tableaux associatifs directement exploitable ensuite dans une boucle foreach
   $data= $stmt->fetchAll(PDO::FETCH_ASSOC);
   unset($db);
   //$data est complet
   if(count($data)>0){
      echo '<pre>';
      print_r($data);
      echo '</pre>';
   }
   //ceci n'est pas une exception 
   //il n'y a peut-etre pas encore de donnees dans la table !
   else{
      echo 'Aucun resultat pour cette requete';
   }
} 
catch (Exception $e) {
   //s'il y a un probleme PHP ou SQL, tout s'affichera ici
   print "Erreur ! " . $e->getMessage() . "<br/>";
}

6 - Requête SELECT avec filtre : lister les enregistrements selon critères

Si par ailleurs, vous souhaitez introduire des filtres à votre requête, votre page contact.php devra être construite comme suit :
On veut faire remonter tous les contacts dont le nom est « CHAZAL » et dont le prénom commence par « C » et dont l’id est strictement supérieur à 2, ce qui doit nous retourner 2 enregistrements :
Testez bien la requête dans votre PHPMYADMIN d’abord !
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
SELECT id, nom, prenom, mail
FROM contact
WHERE nom="CHAZAL" and prenom like "C%" and id > 2
ORDER BY nom, prenom;

On positionne la page contact.php à la racine de notre site. Elle contient ceci :
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs précises de filtres dans l’ordre.
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
//on supprime les guillemets d’une chaîne SQL, PDO s’en occupera
$sql='SELECT id, nom, prenom, mail
FROM contact
WHERE nom= ? and prenom like ? and id > ?
ORDER BY nom, prenom;';
//on initialise notre tableau PHP
$data=array();
$db = include 'db_mysql.php'; 
try {
   //la ligne qui lance la requête préparée
   $stmt = $db->prepare($sql);
   //on affecte les marqueurs précis sur les filtres
   //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire
   $nom='CHAZAL';
   $prenom_debut='C%';
   $id_superieur_a=2;
   //Attention, bien mettre dans l'ordre de la requête ! nom puis prenom_debut puis $id_superieur_a
   $stmt->execute(array($nom,$prenom_debut,$id_superieur_a));
   //$data est un tableau de tableaux associatifs directement exploitable ensuite dans une boucle foreach
   $data= $stmt->fetchAll(PDO::FETCH_ASSOC);
   unset($db);
   //$data est complet
   if(count($data)>0){
      echo '<pre>';
      print_r($data);
      echo '</pre>';
   }
   //ceci n'est pas une exception 
   //il n'y a peut etre pas de CHAZAL avec un prénom qui commence par un C et dont l’id est strictement supérieur à 2
   else{
      echo 'Aucun resultat pour cette requete';
   }
} catch (Exception $e) {
   //s'il y a un problème PHP ou SQL, tout s'affichera ici
   print "Erreur ! " . $e->getMessage() . "<br/>";
}

7 - Requête INSERT : ajouter un enregistrement

Si par ailleurs, vous souhaitez insérer des données dans votre table, votre page contact.php devra être construite comme suit.

On veut insérer un nouveau contact.
Testez bien la requête dans votre PHPMYADMIN d’abord !
Si la requête SQL fonctionne, pensez-bien à supprimer Mme GAILLARD de votre table via PHPMYADMIN, avant de passer à la suite.
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
INSERT INTO contact (id, nom, prenom, mail) VALUES (NULL, 'GAILLARD', 'Geneviève', 'genevieve.gaillard@gmail.com');
On positionne la page contact.php à la racine de notre site. Elle contient ceci :
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs précises de filtres dans l’ordre.
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
//on supprime les guillemets d’une chaîne SQL, PDO s’en occupera
//on remplace l’id auto-increment par NULL, la table s’en chargera
$sql='INSERT INTO contact (id, nom, prenom, mail) VALUES (NULL, ?, ?, ?)';
$db = include 'db_mysql.php';
try { 
   //la ligne qui lance la requête préparée
   $stmt = $db->prepare($sql);
   //on affecte les marqueurs précis sur les filtres
   //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire
   $nom='GAILLARD';
   $prenom='Geneviève';
   $mail='genevieve.gaillard@gmail.com';
   //Attention, bien mettre dans l'ordre de la requête ! Nom puis prenom puis mail
   $stmt->execute(array($nom,$prenom,$mail)) ;
   // on peut récupérer le nombre de lignes affectées 
   $nb_insert = $stmt->rowCount();
   echo $nb_insert.' insertion effectuée<br/>';
   unset($db);
} 
catch (Exception $e) {
   //s'il y a un problème PHP ou SQL, tout s'affichera ici
   print "Erreur ! " . $e->getMessage() . "<br/>";
}

8 - Requête UPDATE : modifier un enregistrement

Si par ailleurs, vous souhaitez modifier des données existantes dans votre table, votre page contact.php devra être construite comme suit.

On veut corriger le mail de Mme ZANZIBAR, car on a mis .ocm au lieu de .com.
Testez bien la requête dans votre PHPMYADMIN d’abord !
Si la requête SQL fonctionne, pensez-bien ensuite à remette l’erreur ‘orange.ocm’ via PHPMYADMIN, avant de passer à la suite.
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
UPDATE contact SET mail = 'zanzo@orange.com' WHERE contact.id = 8;
On positionne la page contact.php à la racine de notre site. Elle contient ceci :
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs précises de filtres dans l’ordre.
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
//on supprime les guillemets d’une chaîne SQL, PDO s’en occupera
$sql='UPDATE contact SET mail = ? WHERE contact.id = ?;';
$db = include 'db_mysql.php';
try { 
   //la ligne qui lance la requête préparée
   $stmt = $db->prepare($sql);
   //on affecte les marqueurs précis sur les filtres
   //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire
   $mail='zanzo@orange.com';
   $id=8;
   //Attention, bien mettre dans l'ordre de la requête !  mail puis id
   $stmt->execute(array($mail,$id)) ;
   // on peut récupérer le nombre de lignes affectées 
   $nb_update = $stmt->rowCount();
   echo $nb_update.' modif effectuée<br/>';
   unset($db);
} catch (Exception $e) {
   //s'il y a un problème PHP ou SQL, tout s'affichera ici
   print "Erreur ! " . $e->getMessage() . "<br/>";
}

9 - Requête DELETE : supprimer un enregistrement

Si par ailleurs, vous souhaitez supprimer des données dans votre table, votre page contact.php devra être construite comme suit.

On veut supprimer l’enregistrement Chantal CHAZAL, car son mail n’existe pas.
Testez bien la requête dans votre PHPMYADMIN d’abord !
Si la requête SQL fonctionne, pensez-bien à remettre Chantal CHAZAL dans votre table via PHPMYADMIN, avant de passer à la suite, et repérez son nouvel id !
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
DELETE FROM contact WHERE contact.id = 6;
On positionne la page contact.php à la racine de notre site. Elle contient ceci :
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs précises de filtres dans l’ordre.
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$sql='DELETE FROM contact WHERE contact.id = ?;';
$db = include 'db_mysql.php';
try {
   //la ligne qui lance la requête préparée
   $stmt = $db->prepare($sql);
   //on affecte le marqueur précis sur le filtre
   //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire
   $id=6;
   $stmt->execute(array($id));
   // on peut récupérer le nombre de lignes affectées 
   $nb_delete = $stmt->rowCount();
   echo $nb_delete.' suppression effectuée<br/>';
   unset($db);
} 
catch (Exception $e) {
   //s'il y a un problème PHP ou SQL, tout s'affichera ici
   print "Erreur ! " . $e->getMessage() . "<br/>";
}

10 - Astuces et erreurs courantes

1 - A proscrire totalement et pour toujours
Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
$sql='SELECT id, nom, prenom, mail
FROM contact
WHERE nom="'.$_POST['nom'].'" and prenom like "'.$_POST['prenom_debut'].'" and id > '.$_POST['id_min'].'
ORDER BY nom, prenom;';
Ceci est la porte ouverte aux injections SQL. PDO en soi ne prévient pas les injections SQL.
https://fr.wikipedia.org/wiki/Injection_SQL
Il vous faut utiliser PDO + les requêtes préparées telles qu’exposées ci-dessus.

2 - PDO plus obscur ?
On peut se dire la chose suivante : Ce qui était bien avec la requête ci-dessus, c’est qu’un simple echo $sql; nous permettait de copier-coller et de tester dans phpmyadmin que tout était bon. Et ça, ce n’est plus possible avec PDO, le rendant plus obscur.
Pourtant, il faut juste inverser la démarche, et ça reste aussi simple. Comme montré dans cet article, on commence par une requête qui fonctionne dans phpmyadmin. Dans $sql, on met des points d’interrogation à la place des valeurs en dur… et enfin, on reporte les valeurs variables PHP dans le array() des paramètres.

11 – Pour aller plus loin

Ici nous avons fait le choix de n’utiliser QUE des marqueurs anonymes (points d’interrogation).
Pour utiliser des marqueurs nommés, car nombre de développeurs trouvent cette méthode plus lisible, merci de lire ce tutoriel qui va bien plus loin que ce petit article d’initiation:
PDO niveau 2 (placeholders)
https://fmaz.developpez.com/tutoriel...omprendre-pdo/

12 – Les participants à ce billet collaboratif

Ceci est un billet collaboratif : Un grand merci donc à tous les participants !
Dans l’ordre alphabétique :
- Andry.ayme
- Celira
- Dendrite
- Jreaux62
- MaitrePylos
- ProgElect
- Rawsrc
- Willy_k
Et merci à LaurentSc pour avoir testé les codes !

Envoyer le billet « PDO une soupe et au lit ! » dans le blog Viadeo Envoyer le billet « PDO une soupe et au lit ! » dans le blog Twitter Envoyer le billet « PDO une soupe et au lit ! » dans le blog Google Envoyer le billet « PDO une soupe et au lit ! » dans le blog Facebook Envoyer le billet « PDO une soupe et au lit ! » dans le blog Digg Envoyer le billet « PDO une soupe et au lit ! » dans le blog Delicious Envoyer le billet « PDO une soupe et au lit ! » dans le blog MySpace Envoyer le billet « PDO une soupe et au lit ! » dans le blog Yahoo

Mis à jour 01/11/2020 à 16h05 par Dendrite

Catégories
PHP , Développement Web

Commentaires

  1. Avatar de Dendrite
    • |
    • permalink
    Bonjour !
    N'hésitez pas à tester et commenter ici si vous rencontrez la moindre difficulté !
    C'est fait pour ça !
  2. Avatar de rawsrc
    • |
    • permalink
    Salut miss,

    le paragraphe 4 (Le bloc try catch : afficher les exceptions) est mal formulé :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    try{ 
       //ici vous écrivez tout votre script
       //On vérifie que notre connexion est bonne avant d'aller plus loin
       $pdo = include 'db_mysql.php';
       if($pdo instanceof PDO) {
          echo 'Connexion réussie ! On peut continuer !';
       }
       else{
          echo 'Connexion ratée ! Essaie encore !';
       }
       //jusqu’à la fin, s’il y a une exception, elle sera interceptée par le catch
    } 
    catch(Exception $e){
       //s'il y a un probleme PHP ou SQL, que ce soit un warning ou une erreur fatale, tout s'affichera ici
       print "Erreur ! " . $e->getMessage() . "<br/>";
    }
    Le code de connexion te renvoie obligatoirement une ressource PDO sinon il déclenche une erreur fatale.
    Donc tout ce code est à remplacer simplement par :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    $pdo = include 'db_mysql.php';
    Après quand tu prépares et exécutes du SQL, il est nécessaire d'encapsuler ces bouts de code dans un try...catch car à l'ouverture de la connexion on indique expressément qu'en cas de problème PDO doit nous avertir en déclenchant une erreur PDOException avec PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    Mis à jour 15/09/2019 à 18h52 par rawsrc
  3. Avatar de Dendrite
    • |
    • permalink
    Salut Raw,

    Merci j'ai corrigé !
  4. Avatar de Willy_k
    • |
    • permalink
    Bonjour,
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'Pour une version supérieure ou égale à 5.3.6, il est conseillé de passer le ;charset dans le DSN http://php.net/manual/fr/mysqlinfo.concepts.charset.php
  5. Avatar de Dendrite
    • |
    • permalink
    Bonjour Willy !
    Ton lien me montre que c'est possible à partir de PHP 5.3.6. Tu as un lien qui me montre que c'est conseillé ?
  6. Avatar de Willy_k
    • |
    • permalink
    Il est marqué

    Ci-dessous les exemples qui démontrent la façon de modifier proprement le jeu de caractères lors de l'exécution en utilisant chacune des APIs.
    Comme un conseil, non ?
  7. Avatar de Dendrite
    • |
    • permalink
    Ok willy. Merci, c'est corrigé.
  8. Avatar de Willy_k
    • |
    • permalink
    Sans filtre, il n y a vraiment aucun gain à préparer la requête, query aurait suffit, et les ; ne sont pas obligatoires.
  9. Avatar de Dendrite
    • |
    • permalink
    Le problème des débutants, c'est qu'ils ne préparent JAMAIS les requêtes quand il le faut. Alors je fais simple. Je leur montre comment TOUJOURS préparer leurs requêtes. Ca manque totalement de nuances ? M'en fous. C'est PDO une soupe et au lit. Pour les nuances, on laisse ici, en commentaire... Donc pour ceux que ça intéresse, Willy a raison.
    Pour le chapitre 5, sans filtre, et celui-là seulement, pas de risque d'injection SQL ! on peut donc se passer de requête préparée, et gagner une ligne.
    en remplaçant

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $stmt = $db->prepare($sql);
    $stmt ->execute();

    par

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $stmt = $db->query($sql);
  10. Avatar de Dendrite
    • |
    • permalink
    Ah oui, je réponds aussi à ceci. Willy dit à juste titre que les ';' ne sont pas obligatoires. On parle bien sûr des ';' du SQL.
    Pour la bonne raison que PDO ne gère qu'une instruction SQL à la fois.
    Si vous souhaitiez créer une table puis la remplir via une requête PDO, vous ne pourriez pas mettre ces 2 instructions dans votre requête. Vous seriez obligé de passer par 2 instructions PDO différentes.
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    CREATE TABLE IF NOT EXISTS `contact` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `nom` varchar(100) NOT NULL,
      `prenom` varchar(100) NOT NULL,
      `mail` varchar(200) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `nom` (`nom`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
     
    INSERT INTO `contact` (`id`, `nom`, `prenom`, `mail`) VALUES
    (1, 'ACCOYER', 'Alain', 'alain.accoyer@gmail.com'),
    (2, 'BRABOIS', 'Bernard', 'bbrabois@yahoo.fr'),
    (3, 'CHAZAL', 'Claire', 'chaz@wanadoo.fr'),
    (4, 'DENDRITE', 'Daisy', 'dendy@gmail.com'),
    (5, 'CHAZAL', 'Etienne', 'chazet@gmail.com'),
    (6, 'CHAZAL', 'Chantal', 'chacha@monfai.fr'),
    (7, 'CHAZAL', 'Kevin', 'kevcha@noos.fr'),
    (8, 'ZANZIBAR', 'Zoé', 'zanzo@orange.ocm'),
    (9, 'CASERATI', 'Michel', 'michoucase@voila.fr'),
    (10, 'FRIPON', 'Françoise', 'francoise.fripon@gmail.com');
  11. Avatar de laurentSc
    • |
    • permalink
    Merci de m'avoir cité dans les remerciements !

    J'ai tout lu. Néanmoins, je n'ai pas accroché sur le chapitre "introduction". Drôle de façon de présenter PDO. Pour moi c'est un gestionnaire de base de données, qui permet de faire abstraction du SGBD et je n'ai pas du tout retrouvé ça dans ton introduction.

    A part ça, très intéressant. Personnellement, comme toi, toutes mes requêtes sont préparées, même si ça sert à rien (une seule méthode pour tout faire) ; par contre, je n'utilise que des marqueurs nommés pour plus de clarté.
  12. Avatar de rawsrc
    • |
    • permalink
    Salut Dendrite,

    juste un conseil, perd l'habitue de fermer tes fichiers.php avec le ?> final.

    Quand un fichier ne contient que du PHP, tu l'ouvres juste avec <?php et c'est tout.

    Au moins t'es sûr de ne pas avoir à chercher ou pourraient apparaître des espaces intempestifs et autres joyeusetés du même acabit.
  13. Avatar de Dendrite
    • |
    • permalink
    Bonjour rawsrc. Ok, merci du conseil. Je corrige pour ce billet.
  14. Avatar de Ciccillo
    • |
    • permalink
    Bonjour, dialogues entre connaisseurs... Moi je rame. Vous vous comprenez au quart de tour et le tuto semble écrit pour des initiés. Par exemple, il faut deviner qu'à un moment donné on parle de contacts.php à créer mais sans le nommer. Il faut s'imaginer qu'il y a une table à créer. Autre exemple, un peu avant les contacts (je crois), il y a un code où l'utilisateur (du tuto) doit le copier-coller après avoir créé la DB. Mais le coller où? Par la suite le bouts de codes m'apparaissent comme des électrons libres... Ils sont reliées par quoi, quelle logique, quel(s) cas? Il manque des exemples.

    Je termine sur un point positif. Ce tuto permet de se poser beaucoup de questions bien formulées par ses divers entêtes de chapitres. C'est bien bien que d'aller à la pêche d'infos sans savoir exactement quoi chercher. Merci.
  15. Avatar de Dendrite
    • |
    • permalink
    Bonjour Cicillo et merci de ton retour.
    Je vais tenir compte de tes remarques sur quelques points "Préciser tout de suite que le script s'appelle contact.php" ou "Préciser où l'on colle le SQL"...
    Pour le reste, ce tuto ne s'adresse pas spécialement aux grands débutants que tu sembles être en PHP-MYSQL, tu as raison, ce tuto essaie de s'adresser à un peu tout le monde. Sur mon blog, je me fais un peu plaisir et je ne reviens pas sempiternellement sur les bases supposées acquises. Beaucoup de gens ont déjà une bonne habitude de développement avec d'autres librairies PHP d'accès aux bases, et surtout l'extension "mysql_" et veulent passer facilement à PDO. J'avoue que c'est d'abord à eux que j'ai pensé. Ce n'est pas une initiation à SQL pour les novices. C'est surtout une initiation simplifiée à PDO.

    Ceci dit, quand je modifierai mon chapitre base de données dans "PHP pour grands débutants pressés", je le simplifierai encore et encore en tenant compte de tes remarques. Et notamment, je séparerai l'initiation à SQL et l'initiation à PDO. Mais pas sur ce billet.
    Bonne continuation !
    Mis à jour 24/07/2018 à 11h55 par Dendrite
  16. Avatar de Xmael
    • |
    • permalink
    Extrêmement intéressant.
    Merci
  17. Avatar de Dendrite
    • |
    • permalink
    Ravie que ça serve !
  18. Avatar de Dendrite
    • |
    • permalink
    Bonjour !

    Mise à jour importante (sur la recommandation de Jreaux), merci à toi.

    1) Bien préciser tôt qu'on n'est pas censé ouvrir et fermer une connexion à chaque requête, parce que ça va mieux en le disant !
    2) Ensuite, pour les requêtes SELECT, écrire directement
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //$data est un tableau de tableaux associatifs directement exploitable ensuite dans une boucle foreach
    $data= $stmt->fetchAll(PDO::FETCH_ASSOC);
    Plutôt que de faire une boucle artificielle.
  19. Avatar de Dendrite
    • |
    • permalink
    Je voulais aussi ajouter quelque chose qui m'est souvent bien utile (mais seulement dans les commentaires cette fois), car c'est une notion un peu plus avancée.
    Souvent, je fais une table avec une clé d'unicité.
    Prenons une table contact('id','mail','pseudo').

    Mettons que 'id' soit auto-incrémenté, que la colonne 'mail' soit le truc unique qu'on ne change jamais...
    J'ai donc posé dans ma table contact une clé d'unicité sur mail. Pas possible de faire un doublon de mail.
    Que se passe-t-il ensuite si 'toto@gmail.com', tête en l'air, est déjà dans ma base, sous le pseudo 'dark_vador', et veut se réinscrire, toujours avec le même mail donc, et le pseudo 'bisounours'... Eh oui, il a changé avec l'âge...

    Je règle ça ainsi en SQL :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO contact VALUES (NULL, 'toto@gmail.com', 'bisounours')
    ON DUPLICATE KEY UPDATE pseudo='bisounours';

    Comme VOUS avez posé la clé d'unicité sur mail, il saura ce qu'est un doublon. Sinon, bien sûr, la db ne prend aucune initiative. Et miracle, dark_vador est devenu bisounours, sans changer de mail.
    Bien entendu, si le mail est absent de la table, c'est une simple insertion. Sinon, c'est une simple modif de pseudo.


    En PHP via PDO, c'est tout à fait possible aussi, avec cette méthode :

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?php
    $sql='INSERT INTO contact VALUES (NULL, ?, ?)
    ON DUPLICATE KEY UPDATE pseudo=?;';
    $db = include 'db_mysql.php';
    try { 
       $stmt = $db->prepare($sql);
       $mail='toto@gmail.com';
       $pseudo='bisounours';
       //c'est ici qu'il faut tilter : $pseudo doit être présent 2 fois ! Rappelez-vous, autant de valeurs que de points d'interrogation au dessus !
       $stmt->execute(array($mail, $pseudo, $pseudo)) ;
       // on peut récupérer une information assez précise (pour mysql du moins)
       $nb_insert = $stmt->rowCount();
       //si c'est 1, il y a eu une vraie insertion, si c'est 2, il y a eu une simple modification du pseudo...
       unset($db);
    } 
    catch (Exception $e) {
       print "Erreur ! " . $e->getMessage() . "<br/>";
    }

    Enjoy !