Forums de WDMédia-Hébergement

Bienvenue sur nos forums

Vous n'êtes pas identifié(e).

#1 18-01-2009 16:18:10

luce
Modérateur
Lieu : GrandesZoreillesLand
Inscription : 31-03-2007
Messages : 245
Site Web

[PHP PDO] Débuter PDO à la place de MySQL, PgSQL...

Salut,

Je débute PDO et j'adore, donc pour vous apprendre la base et vous montrer les avantages (comme quoi il faut s'y mettre), je vous noterais ce que je pense utile pour débuter.


Connexion au serveur de base de donnée
Déjà, je ne parle pas de MySQL, ou autres bases de données, sur wdmedia, PDO gère 5 types de bases de données :
sqlite, pgsql, odbc, mysql, sqlite2

Alors pour ce connecter, c'est tout simple, recopier tel quel, sans modifier les infos de connexion, je veux vous montrer le TRES gros problème de PDO si on fait une connerie !

<?php
    $dbconnect = new PDO('mysql:host=sql.wdmedia.net;dbname=wdmedia_net_1', 'wdmedia_net', 'djlmE353');

(faut mieux que ça ne passe pas, sinon, je vais me faire tuer  par manico !)

Rendez-vous à votre page de test (sur votre hébergement wdmedia) et regardez !

Ca fou les boules !!! Je sais.

Alors, il faut ABSOLUMENT, et ce, pour chaque requete, éviter ce très gros soucis !
Pour ça, on va utiliser un systeme de try catch (utilisé dans énormement de language de programmation) afin de définir ce que l'on veut afficher.

<?php
try {
    $dbconnect = new PDO('mysql:host=sql.wdmedia.net;dbname=wdmedia_net_1', 'wdmedia_net', 'djlmE353');
} catch (PDOException $e) {
    echo "Problème avec la base de donnée / Database error<br/>";
    die();
}

Ici on cache le message d'erreur, mais on pourrait avoir besoin d'un message un peu plus explicite

<?php
try {
    $dbconnect = new PDO('mysql:host=sql.wdmedia.net;dbname=wdmedia_net_1', 'wdmedia_net', 'djlmE353');
} catch (PDOException $e) {
    echo "Problème avec la base de donnée / Database error<br/>".$e->getMessage();
    die();
}

Voila, maintenant, la connerie ne s'affichera pas !

Note pour Manico & Margot :
J'ai lu quelque part que c'etait l'erreur par défaut, donc je pense qu'il est possible de lui interdire d'afficher les identifiants de connexion.

Faire une requete simple
Alors là, ça se complique, en MySQL, pour faire une requete, on utilise mysql_query(), mais voila, pour PDO, c'est un petit peu plus compliquer, il y a 2 méthodes suivant le type de requete.
le QUERY() et le EXEC()
Et en plus de ça, il y a les requetes préparées qui fonctionnent encore différement mais on vera ça après.

On utilise le QUERY() pour les requetes de types SELECT, et le EXEC() pour les requetes de type INSERT, DELETE, UPDATE.

Pour le test, créer une table nommé "pdotest", avec 2 champs ( champs1 champs2) et faites quelques insertions dedans.

Corriger le $dbconnect pour avoir vos bons identifiants.
Vous remarquerez aussi le mysql: devant, c'est parce que j'utilise une base de donnée mysql, mais vous pouvez utiliser une des 4 autres, pas de soucis !
Ah tiens, vous avez tilté ?
Que je fasse mes requetes en MYSQL, pour une base de donnée PGSQL, c'est pas du tout un soucis pour PDO !!! (c'est genial !)

Maintenant un simple select :

try 
{
	$req = $dbconnect->query('SELECT champs1, champs2 FROM pdotest');
	$res = $req->fetchAll(PDO::FETCH_ASSOC);
	$compte = $req->rowCount();
	echo '<h1>Nombre de résultat '.$compte.'</h1>';

	foreach($res as $a)
	{
		echo 'champs 1 = '.$a[champs1].' champs2 = '.$a[champs2].'<br>';
	}
} catch (PDOException $e) {
	echo "Problème pour lister<br/>Opération annulée";
	die();
}

Vous voyez les différences par rapport à MySQL, rowCount() est l'équivalent de num_rows
On utilise fetchAll() si on doit obtenir plusieurs lignes, sinon on utilise fetch().

Les requetes préparées

Allez, on va comparer mysql à pdo, c'est marrant :-P

$sql = "INSERT INTO pdotest (champs1, champs2) VALUE ($_GET['champs1'], $_GET['champs2'])";
mysql_query($sql);

Voila, une chose à ne JAMAIS faire ! c'est vraiment une énorme faille de sécurité !!!!

La même réquete avec PDO et les requetes préparées :

try {
	$req = $dbconnect->prepare("INSERT INTO pdotest (champs1, champs2) VALUES (?, ?)"); 
	$req->execute(array($_GET['champs1'], $_GET['champs2']));
} catch (PDOException $e) {
	echo "Problème pour enregistrer";
	die();
}

Voila une autre chose à ne JAMAIS faire avec PDO, le MYSQL_REAL_ESCAPE_STRING() !!!
Et oui, PDO sécurise toutes les entrées avec les  requetes préparées.
Vous avez aussi remarqué que le système change par rapport au requete simple, on lui donne le schema de la requete, les valeurs sont remplacées par des ?
Ensuite, on execute la requete avec les valeurs dans un array(), et il sécurise tout comme un grand !

Notez bien qu'il faut tout de même vérifier ce que l'on va injecter dans la requete, le contenu, que ce soit une tentative de piratage par exemple, sera enregistrés dans le champs, donc il faut tout de meme appliquer quelques vérification, si par exemple  on veut un nombre entier, utiliser un is_int($_GET['champs1']).

Libérer la mémoire / fermer la connexion sql
Sous MySQL pour libérer la mémoire on utilise
mysql_free_result($res);
Et pour fermer la connexion sql on utilise
mysql_close();

Sous PDO, on ferme la connexion comme ça :
$dbconnect = NULL;
(Que l'on peut faire après le FETCH)
Et une fois que l'on a tout afficher, un libère la mémoire
$res = NULL;

C'est tout de même plus simple à retenir :-D
Intéressant
Si dans un try catch, vous executez plusieurs requetes en même temps, et qu'une erreur se produit, sous MYSQL, il faut prévoir le coups et tout effacer, avec PDO, il y a une fonction pour ça, c'est le rollBack() (Retour en arrière en francais).

J'ai fait de la comptabilité quand j'étais à l'école, et ma prof de compta n'arrêtait pas de nous dire "Un bon comptable et un grand fénéant !" (Mlle Muriel Egasse).
Je crois qu'à partir de maintenant, on peut dire aussi : "Un bon webmaster est un grand fénéant, il utilise PDO !"

Voila, j'espère vous avoir donner une bonne raison pour apprendre PDO, et si vous voulez pas vous prendre la tête avec ça, bah PDO sera obligatoire pour PHP6, alors, autant commencer maintenant !

Ceci dit, je débute en PDO, je ne connais pas tout, mais je pense que  PDO est génial, je posterais un exemple de script "news" basic pour vous montrer que c'est très facile.

Hors ligne

#2 11-02-2009 11:43:54

luce
Modérateur
Lieu : GrandesZoreillesLand
Inscription : 31-03-2007
Messages : 245
Site Web

Re : [PHP PDO] Débuter PDO à la place de MySQL, PgSQL...

Salut,

Pour utiliser les LIMIT, comme c'est des INT, il faut le préciser, ce qui nous oblige donc à utiliser les BIND

Voici un exemple fait pour Eric Renaud :

			$req1 = $dbconnect->prepare('SELECT id_news, titre, text, UNIX_TIMESTAMP(date_news) as temps FROM eric_news ORDER BY date_news DESC LIMIT ?,?');
			$req1->bindParam(1, $next, PDO::PARAM_INT);
			$req1->bindParam(2, $fin, PDO::PARAM_INT);

Il existe deux manières pour les BIND, soit en remplacant les ? par des :nomdubind (avec : devant)  puis à la place des chiffres, mettre ':nomdubind' ou alors, ce que je trouve le plus simple, utiliser la position du bind sans les nommés
donc le premier ? est 1, le deuxieme ? est 2.
Le soucis des bind, c'est que pour chaque ? il faut déclarer le bindparam en fonction de son contenu.

Hors ligne

Pied de page des forums