Recommended Posts

Niveau requis Intermédiaire

Temps estimé : 30 minutes

Bonjour,

 

Je me permet de l'approfondir un peu afin de faciliter votre usage de PDO. Si c'est le cas, c'est partit ! J'ai pas relu ni vraiment trop testé mon code, il est tard et j'ai tout recodé pour vous car j'utilise une façon un peu plus compliquée (orientée objet) et je voulais faire un truc plus accessible.

 

Préparation

 

Révélation

 

<?php
//ajoutez cette fonction à votre librairie.
function PDOConnect($DB_DSN, $DB_LOGIN, $DB_PASSWORD)
{
try
{
               $oPDO = new PDO($DB_DSN, $DB_LOGIN, $DB_PASSWORD);
}
catch (PDOException $e)
{
                die('Erreur : '.$e->getMessage());
}

$oPDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
return $oPDO;
}
?>
La fonction PDOConnect() sert bien évidement à se connecter à PDO. Puis ensuite dans votre fichier de configuration ajoutez les lignes suivantes:
<?php
define('DB_SERVEUR', '127.0.0.1');
define('DB_LOGIN', 'root'); //Votre login pour la connection à MySQL
define ('DB_PASSWORD', ''); //Bien évidément, mot de passe.
define('DB_NAME', 'database'); //Base de donnée
define('DB_DSN', 'mysql:host='. DB_SERVEUR .';dbname='. DB_NAME); //changez ici mysql si vous utilisez un autre SGBD
?>
Ce sont des constantes qui stockent les informations de connexion à PDO, vous n'avez qu'à modifier leurs valeurs si vous changez d'informations de connexion.
<?php
//exemple d'une page "index.php".
require_once 'config.php'; // Votre fichier de config qui stocke les constantes.
require_once 'librairies.php'; // Votre librairie qui contient PDOConnect();

$oPDO = PDOConnect(DB_DSN, DB_LOGIN, DB_PASSWORD); // Instanciation de PDO avec les constantes magiques 

// Votre code a exécuter.

$oPDO = null; // Fermeture de la connection.
?>

 

 

Exécuter une Requête

 

Révélation

 

Révélation

 

Avec PDO, on peut exécuter des requêtes par plusieurs méthodes :

 

  • query()
  • prepare() & execute()
  • exec() (spéciale, donc lisez attentivement ce qui suit)

 

Toutes ces méthodes sont en réalités bien différentes et je vais expliquer pourquoi choisir une méthode plutôt qu'une autre.

 

 

Les Méthodes Prepare() et Execute()

 

Révélation

 

Description de ces Méthodes

 

Révélation

Ces deux méthodes servent à créer des requêtes préparées. Elles permettent d'utiliser des variables dans des requêtes en évitant les injections SQL. Donc n'utilisez pas prepare() et execute() sans utiliser de variable, en plus ça augmenterait bêtement le temps d'exécution de la page.

 

Exemple d'Utilisation

 

Révélation

Je souhaite récupérer tout les jeux vidéos de ma table jeux_vidéos qui sont sortis telle ou telle autre année. Seulement, l'année est définie dans l'URL par mapage.php?&annee=2005 (donc récupérable dans PHP par $_GET['annee']). Étant donné que l'utilisateur peut modifier l'URL, il peut mettre du code dans l'URL et injecter des données ou du code malveillant dans notre site/database. C'est pourquoi nous utilisons ces méthodes.

 

Code de l'Exemple d'Utilisation

 

Révélation

 



// code à insérer parmi l'exemple de page d'index plus haut.
$req = $oPDO->prepare('SELECT * FROM jeux_videos WHERE annee_sortie = :annee'); // On prépare la requête.
$req->bindParam(':annee', $_GET['annee'], PDO::PARAM_INT); //On ajoute un marqueur de nom :date.
$req->execute(); // On exécute la requête.
$data = $req->fetchAll(); // On met les résultat dans un tableau, en l'occurrence: $data.

 

 

Explications

 

Révélation

 

$req->bindParam ? Gné ? PDO::PARAM_INT ? Gnéééé ?

La méthode bindParam() permet d'ajouter une valeur à un marquer, vous remarquerez que le marqueur est placé préalablement dans la requête préparée: [...] WHERE date_sortie = :date [...]

PDO::PARAM_INT est une constante (PARAM_INT) de la classe PDO (si vous ne savez pas ce qu'est une constante en PHP, renseignez vous sur internet). Elle indique que le marqueur :date est de type integer; c'est à dire, un chiffe (ou nombre). Il y a d'autres constantes comme PDO::PARAM_STR pour un marqueur de type string (chaîne de caractères, de lettres quoi), PDO::PARAM_BOOL pour les booléens (true et false)

Il y a bien évidement d'autres constantes pour bindParam(), et d'autres façon de procéder (sécurisée aussi), mais c'est aussi à vous de vous renseigner, bien que celle-là reste quand même la meilleure pour moi.

Pour finir, vous verrez qu'on utilise la fonction fetchAll(), elle sert à mettre TOUTES les lignes retournées dans la requête dans le tableau. Si vous souhaitez récupérer qu'une seule ligne, utilisez alors la fonction fetch().

 

 

Compter le Nombre de lignes correspondantes à la Requête
 

Révélation

 

Si vous voulez savoir combien de lignes correspondent à votre requête exécutée par execute(), utilisez alors la fonction rowCount(). La fonction rowCount() vous retourne le nombre de lignes correspondantes à votre dernier execute(); elle ne peut donc pas s'utiliser sur query() ni sur exec().

 

Exemple

 



// code à insérer parmi l'exemple de page d'index plus haut.
$req = $oPDO->prepare('SELECT * FROM jeux_videos WHERE date_sortie = :date'); // On prépare la requête.
$req->bindParam(':date', $_GET['annee'], PDO::PARAM_INT); // On ajoute un marqueur de nom :date. J'expliquerai ça après.
$req->execute(); // On exécute la requête.
$nb_jeux = $req->rowCount();
$year = (int) $_GET['annee'];
echo $nb_jeux . ' jeux sorti(s) en ' . $year . '.'; 

 

 

 

 

La Méthode Exec()

 

Révélation

 

Description

 

Révélation

 

exec() exécute une requête SQL dans un appel d'une seule fonction, et retourne le nombre de lignes affectées par la requête.

Attention, elle ne retourne pas le nombre de ligne retournées, mais affectées. C'est quoi la différence? Et bien, on parle de lignes dites "retournées" lorsqu'on utilise des requêtes SQL de type SELECT (et oui, SELECT nous "retourne" les lignes correspondantes à la requêtes), et on parle de lignes dites "affectées" lorsqu'on utilise d'autres requêtes SQL qui doivent modifier votre base de données. C'est à dire, INSERT, UPDATE, DELETE, TRUNCATE, etc.

 

 

Exemple d'Utilisation

 

Révélation

Je souhaite exécuter une requête simple (sans variable) mais qui modifie ma base de donnée (donc autre que SELECT).

 

Code de l'Exemple d'Utilisation

 

Révélation

 


<?php
// code à insérer parmi l'exemple de page d'index plus haut.
$oPDO->exec('UPDATE jeux_video SET prix = 10, nbre_joueurs_max = 32 WHERE nom = \'Battlefield 1942\'');
?>
Attention: Ne tombez pas dans le piège! N'utilisez pas exec() si vous devez utiliser des variables modifiables par l'utilisateur dans vos requêtes (comme toutes les superglobales) ! JAMAIS !

 

 

La Spécialité de Exec()

 

Révélation

 

Comme dit dans le paragraphe de description de exec(), elle retourne le nombre de lignes affectées. Pour utiliser, ou afficher ce nombre de lignes, il suffit de le stocker dans une variable:


<?php
// code à insérer parmi l'exemple de page d'index plus haut.
$nb_modifs = $oPDO->exec('UPDATE jeux_video SET possesseur = \'Florent\' WHERE possesseur = \'Michel\'');
echo $nb_modifs . ' entrées ont été modifiées !';
?>

 

 

 

La Méthode Query()

 

Révélation

 

Description

 

Révélation

query() exécute une requête et retourne un jeu de résultat. Donc à utiliser dans les autres cas. Haha. :P Si vous ne voulez pas modifier votre base de données (donc faire un SELECT ou SELECT COUNT(*) ). Pareil que pour exec(), n'utilisez pas query() si vous devez utiliser des variables modifiables par l'utilisateur dans vos requêtes !

 

Exemple d'Utilisation

 

Révélation

Je souhaite exécuter une requête simple qui me retournera un jeu de résultat (donc un SELECT, ou SELECT COUNT(*) )


Code de l'Exemple d'Utilisation

 

Révélation

 


<?php
// code à insérer parmi l'exemple de page d'index plus haut.
$reponse = $oPDO->query('SELECT nom FROM jeux_video WHERE possesseur=\'Patrick\'');
?>
Attention : Encore une fois, n'insérez aucune variable dans votre requête! Si vous voulez utilisez des variables, utilisez prepare() et execute() !

 

 
 
Extra

 

Révélation

 

Quand vous allez utiliser des fonctions pour construire votre projet, vous allez vous rendre compte que c'est embêtant de devoir instancier PDO à chaque fois car la variable $oPDO n'est pas portable jusqu'à l'intérieur des fonctions ! La solution à ça ? Le mot-clé: global ! A quoi il sert lui ? Et bien à rendre la variable $oPDO portable jusqu'à l'intérieur de notre fonction ! Un exemple concret ? Ajoutez cette fonction à votre librairie :

<?php
function ajouter_gens($nom, $prenom){
     global $oPDO;

     $sql = $oPDO->prepare("INSERT INTO gens
                                          VALUES (:nom, :prenom)"); //On prépare la requête
     $sql->bindParam(':nom', $nom, PDO::PARAM_STR);
     $sql->bindParam(':prenom', $prenom, PDO::PARAM_STR);
     $data = $sql->execute(); // On execute la requête préparée.
}
?>
Et on va reprendre la page d'index de tout à l'heure et vous allez voir c'est plutôt facile :
<?php
require_once 'config.php'; // Votre fichier de config qui stocke les constantes.
require_once 'librairies.php'; // Votre librairie qui contient PDOConnect() et ajouter_gens()

$oPDO = PDOConnect(DB_DSN, DB_LOGIN, DB_PASSWORD); // Instanciation de PDO.

//On appelle la fonction ajouter_gens.
ajouter_gens('Roger', 'Dupont'); //ajout de la personne par appel de la fonction.

$oPDO = null; // Fermeture de la connexion.
?>

 

 

 

Cordialement,

Hey hey

Share this post


Link to post
Share on other sites

Up du sujet + Correction + Mise en page plus correcte + Ajout de l'équivalant de mysql_num_rows() sans utiliser rowCount().

 

N'hésitez pas à poser vos questions, je me suis mit à PDO y'a pas si longtemps, j'ai galéré quand même et je pense que ça peut vous éviter de longs moments de recherche xD Mais vraiment, c'est beaucoup mieux que les mysql_* :)

Share this post


Link to post
Share on other sites

Nouveau up du sujet et bien mérité, j'ai refais toute la mise en page du tuto pour faire en sorte que ça devienne plus compréhensible.

 

A prévoir:

- explications des constantes PDO::FETCH_*

- exécuter une requête préparée sans marqueur de nom.

 

Donc voilà, revenez jeter un coup d'oeil, merci pour vos commentaires, et encore une fois, si vous avez des questions, n'hésitez pas. :)

Share this post


Link to post
Share on other sites

En passant sur les fautes ...

Attention: Encore une fois, n'insérez aucune variable dans votre requête! Si vous voulez utilisez des variables, utilisez prepare() et execute() !

Et PDO::quote(), alors ?

Share this post


Link to post
Share on other sites

Merci pour vos commentaires!

 

Nami-Doc > Le tuto est loin d'être finit, là j'ai eu pas mal de gros problème IRL et je sais pas vraiment quand écrire la suite. Pour l'instant, c'est juste une approche de PDO comme tu peux le remarquer. Néanmoins, je vais la mettre sur la liste des choses à expliquer, car elle peut quand même s'avérer utile. :)

Share this post


Link to post
Share on other sites

Tu as lu mon tuto avant de dire que j'ai copié ? Parce qu'il n'a vraiment rien à voir avec le tuto du site du zero.

 

J'ai repris des requêtes SQL, c'est tout, et c'est indiqué dans mon tuto.

 

Donc je t'en prie, lis mon tuto, et vérifies bien si c'est la même chose que celui du SdZ.

Share this post


Link to post
Share on other sites

Pseudo de kikoo, avatar de kikoo, et bien évidemment réponse de kikoo qui prouve que tu ne lis pas.

 

Euh, tu parles de moi là ? oÔ

 

 

(+ Quelques corrections de code)

 

 

Share this post


Link to post
Share on other sites

Si c'était pour moi, juste, Olol.

 

Car je suis désolé, mais un O rime pas avec un Y. Sinon, niveau de la difficulté, je sais bien que PDO va avec easy.

C'était bien toi :)

 

Share this post


Link to post
Share on other sites