PDO

Introduction

PDO (PHP Data Objects) est une extension PHP qui permet d'utiliser une base de données en programmant avec un style orienté objet, et surtout qui permet de s'affranchir du SGBD

PDO est une extension PHP. Il faut installer le pilote PDO générique ainsi que chacun des pilotes de SGBD que l'on souhaite utiliser.
Si vous souhaitez l'utiliser en local avec Wamp par exemple, vérifier que l'extension est bien coché, coté hébergeur, vous pouvez vérifier via le phpinfo.

Pourquoi ce tutoriel ? vous me direz qu'il en existe sur Internet, cependant je me suis mis à PDO il y a peu, personnellement je suis plus à l'aise d'écrire des requêtes PDO que des requêtes MySQL. Pour apprendre PDO j'ai lu une quantié non négligeable d'articles, de tutoriels sur des sites français (il y en a peu, mais aussi sur des sites en anglais qui sont plus nombreux, et j'ai également lu tous les topics du forum sur Developpez.net.

Vous pouvez consulter aussi cette adresse fort instructive : http://fmaz.developpez.com/tutoriels/php/comprendre-pdo/

Pendant le développement, j'ai eu des erreurs, mais ces erreurs mon appris à mieux me servir de PDO, et puis c'est en faisant des erreurs que l'on progresse, n'est ce pas !

Conclusion, j'ai réussi, mon nouveau site qui est tout en PDO.

Dans cet article, je vais présenter ce que j'ai fait et utilisé. Attention, toutes les requêtes sont insérées dans un bloc (try / cache).

Connexion à PDO

Type de connexion à une base de données avec PDO que l'on place dans un fichier et en faisant un appel avec (include_once).

            $db_host = 'localhost';
            $db_name = ''; //nom de votre bdd
            $db_user = ''; //nom utilisateur
            $db_pass = ''; //mot de passe
          // Connexion à la base
          try {
              $strConnection = 'mysql:host='.$db_host.';dbname='.$db_name; //Ligne 1
              $arrExtraParam= array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"); //Ligne 2
              $PDO = new PDO($strConnection, $db_user, $db_pass, $arrExtraParam); //Ligne 3; Instancie la connexion
              $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);//Ligne 4
          }
          catch(PDOException $e) {
              $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
              die($msg);
          }
		

Fonction de connexion PDO

Fonction de connexion, qui peut être utilisé dans d'autres fonction, pour cela dans la nouvelle fonction on l'appelle ainsi ($PDO = connexion_DB(); ). En tout état de cause il vaut mieux éviter d'utiliser Le mot clé global dans la nouvelle fonction.
Plus d'info ici http://www.developpez.net/forums/d1001002/php/langage/fonctions/porte-variable-d-instanciation-d-objet-pdo/

          function connexion_DB()
          {
              $db_host = 'localhost';
              $db_name = ''; //nom de votre bdd
              $db_user = ''; //nom utilisateur
              $db_pass = ''; //mot de passe
              // Connexion à la base
              try {
                  $strConnection = 'mysql:host='.$db_host.';dbname='.$db_name; //Ligne 1
                  $arrExtraParam= array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"); //Ligne 2
                  $PDO = new PDO($strConnection, $db_user, $db_pass, $arrExtraParam); //Ligne 3; Instancie la connexion
                  $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);//Ligne 4
              }
              catch(PDOException $e) {
                  $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
                  die($msg);
              }
              return $PDO;
          }
		

Deconnexion classique

Code de déconnexion, la variable $PDO correspond à la variable d'instance PDO.

          // Fermer la connexion du serveur
          $stmt->closeCursor();
          //Détruire l'objet PDO
          $pdo = null;
		

Fonction de déconnexion

Fonction de déconnexion que l'on appelle dans la page.

          function deconnexion_DB() {
              $PDO = NULL;
          }
		

Requête SELECT avec (query)

Requête SELECT avec plus rapide, certe mais moins sécurisée, tout dépend dans quel contexte on l'utilise, toutefois toutes données provenant d'utilisateur les requêtes, selon moi doivent être préparée.

              try {
                $query_RsCategorie = "SELECT * FROM free_down_categories ORDER BY catname ASC";
                $reqcat = $PDO->query($query_RsCategorie);
              }
              catch(PDOException $e) {
                  $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
                  die($msg);
              }
		

Requête SELECT avec (prepare)

Requête SELECT ayant une valeur provenant d'une variable global $_GET, Le « intval » permet de ne laisser passer que les nombres entiers, si ce dernier provient d'un utilisateur.

          try {
          $stmt = $PDO->prepare("SELECT * FROM tuto WHERE id_tuto = :id");
          $stmt->bindValue(':id', intval($_GET['id_tuto']));
          $stmt->execute();
          $result = $stmt->fetchObject();		
          }
          catch(PDOException $e) {
              $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
              die($msg);
          }
		

Requête INSERT INTO

Ci-dessous une requête INSERT avec des valeurs provenant d'un formulaire.

          $tabsql = array( //champ table tuto_pres
                      ':titre' => $_POST["titre"],
                      ':description' => $_POST["description"],
                      ':lien' => $_POST["lien"],
                      ':today' => $_POST["today"],
                      ':maj' => $_POST["maj"],
                      ':categ' => $_POST["categorie"],
                      ':new' => $_POST["new"],
                      ':vis' => $_POST["vis"]
          );
        // vérification des champs 
        // votre code
            try
            {
             $sql = "INSERT INTO tuto_pres (titre_tuto, meta_description, lien, date_tuto, date_maj, categorie, new, visible) VALUES (:titre, :description, :lien, :today, :maj, :categ, :new, :vis)";
             $reqsql = $PDO->prepare($sql);
             $resultsql = $reqsql->execute($tabsql);
            }
            catch(PDOException $e) {
                $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
                die($msg);
            }
		

Requête UPDATE

Ci-dessous une requête UPDATE effectuée avec un formulaire affiché avec un lien de type GET d'une autre page.

            $id = $_GET['id'];
            if ((isset($_POST["MM_update"])) && ($_POST["MM_update"] == "form1")) {
              
              $titre = $_POST['titre'];
              $description = $_POST['description'];
              $lien = $_POST['lien'];
              $date_rss = $_POST['date_rss'];
               try {
                  $updateSQL = $PDO->prepare("UPDATE rss_fichier SET titre=?, description=?, lien=?, date_rss=? WHERE id=?");
                  $up = $updateSQL->execute(
                  
                        array(
                            $titre,
                            $description,
                            $lien,
                            $date_rss,
                            $id
                        )
                  );
              }
              catch(PDOException $e) {
                  $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
                  die($msg);
              }
              
            echo '<script>setTimeout("window.location.href=\'rss_liste.php \' ", 1000);</script>';
            }
		

Requête DELETE

Requête permettant à partir d'un lien avec GET d'effectuer la suppression d'un enregistrement.

          try {
              $sql = "DELETE FROM tuto_pres WHERE id_tuto = :id_tuto";
              $query = $PDO->prepare($sql);
              $query->bindParam(':id_tuto', $_GET['id_tuto'], PDO::PARAM_INT);
              $query->execute();
              header("location: tuto_liste.php");
          } catch (PDOException $e) {
              echo 'PDOException : '.  $e->getMessage();
          }
		

Requête COUNT

Compter le nombre de résultat.

            try {
                  $qryCount = "SELECT COUNT(*) id_tuto FROM tuto_pres";
                  $stmt = $cnx->query($qryCount);
                  $result = $stmt->fetchAll();
                  echo 'Nombre d\'enregistrements = ' . $result[0]['id_tuto'] . '
'; } catch (Exception $e) { $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage(); die($msg); }

Requête COUNT avec fetchColumn()

Compte le nombre de résultat mais avec une colonne de la table définie.

            try {
                $nbd = $PDO->query('SELECT COUNT(*) FROM free_accordion_menu WHERE categ_menu = "1"')->fetchColumn();            }
            catch (Exception $e)
            {
                $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
                die($msg);
            }
            //Utilisation
            Il y a <?php printf($nbd); ?> Tutoriels.	
		

Liste déroulante

Liste (select) généré avec une requête PDO.

          try {
          $query_RsCategtuto = $PDO->prepare("SELECT * FROM tuto_categ WHERE link='0'");
          $query_RsCategtuto->execute();
          $row_RsCateg = $query_RsCategtuto->setFetchMode(PDO::FETCH_ASSOC);
          }
          catch(PDOException $e) {
              $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
              die($msg);
          }
         
            // code de la liste dans le body
          <select name="categorie" id="categorie">
                  <option value="" 
                  <?php 
                  $OK = isset($_POST["categorie"]) ? true : false;
                  if ($OK && $_POST["categorie"] == "") { ?>
                  selected="selected"
                  <?php } ?>
                  >...Choisir une catégorie...</option>
                  <?php
                  while ($row_RsCateg = $query_RsCategtuto->fetch(PDO::FETCH_ASSOC)) {
                  ?>
                  <option value="<?php echo $row_RsCateg['catid']?>"><?php echo $row_RsCateg['catname']?> N° <?php echo $row_RsCateg['catid']?></option>
                  <?php
                  } 
                  ?>
                  </select>
		

Si données existe

Vérifie si lors de la saisie dans un champ sensible, si la valeur du champ du formulaire n'est pas déjà dans la table.

          if (!empty($_POST["lien"]))
          {
                       $sql4 = $PDO->prepare("SELECT id_tuto FROM tuto_pres WHERE lien= :lien");
                       $sql4->execute(array('lien' => $_POST["lien"]));
                       $count = $sql4->rowCount();
                        //si la requete ne retourne rien, cela signifie que le lien n'existe pas
                        if($count > 0)
                        {
                         $message .= 'Le lien dans la table xx existe deja';
                        }
          }