JeuWeb - Crée ton jeu par navigateur
PDO : Comment ça marche - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : PDO : Comment ça marche (/showthread.php?tid=4553)

Pages : 1 2


PDO : Comment ça marche - Ekilio - 22-01-2010

Bonjour à tous,

Ayant commencé depuis quelques mois ma transition de mysql_* à PDO, je viens vous proposer un petit retour, sous forme de tutoriel, à ce sujet. Le but sera de bien comprendre PDO, ses avantages et son mode d'emploi, puis de proposer quelques codes pour l'utiliser.

Note : je n'aborderais pas ici les outils utilisant PDO comme Zend_Db ou Symfony, cela déborderait du cadre de cet article.

I/ PDO, pourquoi ?

Tout d'abord, la question qui vient à l'esprit lors du passage vers PDO, c'est : pourquoi faire ? Après tout, ça marchait très bien avant ! Et bien, il y a plusieurs raisons à cette transition.

La première raison est purement pratique : lors de l'arrivée de PHP 6, d'ici quelques temps tout de même, les fonctions mysql_* et mysqli_* seront dépreciées et passées en module de PEAR ; par conséquent, petit à petit, les hébergeurs cesseront le support de ces fonctions. Bien sûr, il y a du temps, mais autant prendre directement les bonnes habitudes, non ?

La seconde raison est liée à la sécurité : l'utilisation de PDO et des requêtes préparées permet, nous le verront, de supprimer les risques d'injections SQL dans vos scripts.

La troisième raison est l'interopérabilité : en utilisant PDO, vous pouvez facilement changer de SGBD, alors qu'avec les fonctions mysql_*, c'est tout votre code que vous deviez reprendre.

Il y a d'autres raisons, mais ce sont les plus importantes à mes yeux.

II/ PDO, les bases

PDO est séparée en trois classes différentes, et toutes aussi utiles les unes que les autres : PDO, PDOStatement, PDOException.

PDO est la classe de base : c'est elle qui gère les requêtes et les relations à la base au sens propre.

PDOStatement est la classe qui gère à la fois la préparation des requêtes et leurs retours ; c'est la classe de résultats, en quelques sortes.

PDOException est, comme son nom l'indique, la classe d'exception de PDO. Je ne m'étendrais pas là-dessus, le système d'Exception est complexe.

III/ Les DSN et la connexion

Commençons par le commencement : la connexion à une base de données. Pour se connecter, PDO utilise ce que l'on appelle un DSN (Data Source Name). Pour faire simple, c'est une chaine de caractères qui contient la description de la base sur laquelle on souhaite se connecter.

Un DSN ressemble à ceci :

Code :
mysql:dbname=mabase;host=127.0.0.1

Examinons les parties importantes. Le "mysql" en début de chaine indique que l'on se connecte à un serveur mysql. Actuellement, PDO supporte MySQL, MS SQL Serveur, Firebird, Interbase, IBM, Informix, Oracle, ODBC, DB2, PostgreSQL, SQLite et 4D (attention, certains de ces supports sont expérimentaux).

Le dbname= indique le nom de la base de données où nous allons nous connecter (ici "mabase"). C'est l'équivalent de l'ancienne fonction "mysql_select_db" ou de la commande SQL USE

Le host= indique le nom du serveur sur lequel nous allons nous connecter ; ici 127.0.0.1, donc en local.

Ce DSN doit être passé à PDO, ainsi que deux autres arguments : le nom d'utilisateur et le mot de passe. Tout ceci dans le constructeur ; la création d'une connexion avec PDO ressemble donc à ça :

Code PHP :
<?php 
$pdo
= new PDO('mysql:dbname=mabase;host=127.0.0.1', 'root', 'password');

Simple, non ? Il est maintenant important de gérer les exceptions, cela se fait comme ceci :

Code PHP :
<?php 
try {
$pdo = new PDO('mysql:dbname=mabase;host=127.0.0.1', 'root', 'password');
} catch (
PDOException $e) {
echo
'Erreur de connexion : ' . $e->getMessage();
}

Et voila, tout est prêt à être utilisé !

IV/ Les requêtes non-préparées

Le premier usage, le plus simple et le plus rapide (mais le moins sécurisé) de PDO, est l'utilisation des requêtes non-préparées.

Pour faire simple, les requêtes non-préparées sont l'équivalent de notre ancien mysql_query : on prends du texte et on l'execute directement sur notre serveur. C'est la méthode la plus rapide si on ne doit executer une requête qu'une seule fois et qu'elle n'a pas de paramètres.

L'execution de requêtes non-préparées se fait via la fonction query, comme ceci :

Code PHP :
<?php 
$sql
= 'SELECT id FROM users';
$result = $pdo->query($sql);

L'object obtenu en réponse sera du type PDOStatement, nous verrons ensuite comment traiter son résultat.

Notez que les chaines passées via query doivent impérativement être sécurisées ; si vous tenez absolument à utiliser des paramètres entrés par l'utilisateur dans de telles chaines, pensez à utiliser une fonction d'echapement. Notez que mysql_real_escape_string ne fonctionne pas avec PDO ; vous pouvez utiliser $pdo->quote($texte) pour la remplacer, mais d'une manière générale, les requêtes avec des paramètres doivent être préparées.

V/ Utiliser l'object PDOStatment pour un résultat

Nous l'avons vu, la fonction query() retourne un objet de type PDOStatment. Cet objet peut être utilisé de plusieurs façons.

1) La fonction fetch()

La première méthode, et la plus proche des anciennes fonctions mysql_*, est l'utilisation de sa méthode fetch(). Fetch() fonctionne globalement comme les anciens mysql_fetch_* : cela renvoi la ligne suivante sous la forme que l'on défini par une constante. Voici un exemple :

Code PHP :
<?php 
// On se connecte
$pdo = new PDO('mysql:dbname=mabase;host=127.0.0.1', 'root', 'password');

// On execute une requête
$sql = 'SELECT id FROM users';
$result = $pdo->query($sql);

// On récupère la première ligne du résultat
$ligne = $result->fetch();

// On affiche l'id
echo $ligne['id'];

// On récupère la ligne suivante sous forme d'objet
$ligne = $result->fetch(PDO::FETCH_OBJ);

// On affiche l'id
echo $ligne->id;

Les valeurs possibles sont les suivantes pour le paramètres de fetch (le type d'association) :

PDO::FETCH_ASSOC pour obtenir un table associatif (colonne => valeur)
PDO::FETCH_BOTH pour un tableau association et numérique (colonne => valeur ET numero_de_colonne => valeur). C'est la valeur par défaut.
PDO::FETCH_CLASS pour une classe que vous définissez. J'y reviens un peu plus tard.
PDO::FETCH_INTO pour une classe définie et déjà existante que vous mettez à jour à chaque fetch (j'y reviens aussi)
PDO::FETCH_LAZY pour créer un objet standard (stdClass) dont les variables sont créées uniquement lorsqu'on tente d'y faire appel.
PDO::FETCH_NUM pour un tableau numérique
PDO::FETCH_OBJ pour un objet standard (stdClass) dont les propriétés sont les colonnes de la requête

Maintenant, revenons un instant sur les type de CLASS. Le principe est le suivant : vous fournissez à PDO un objet de votre choix, que vous avez créé ; et cet objet sera rempli automatiquement par PDO avec les valeurs sélectionnées.

Dans le cas de PDO::FETCH_CLASS, vous devez utiliser au préalable la fonction setFetchMode() sur votre objet de résultat. Cette fonction permet de définir le mode de distribution pour tous les fetch suivants, et si son mode est sur FETCH_CLASS, elle prends en second paramètre le nom de la classe, comme ceci :

Code PHP :
<?php 
// On se connecte
$pdo = new PDO('mysql:dbname=mabase;host=127.0.0.1', 'root', 'password');

// On execute une requête
$sql = 'SELECT id, nom FROM users';
$result = $pdo->query($sql);

// On choisi le mode de distribution
$result->setFetchMode(PDO::FETCH_CLASS, 'user');

A partir de là, les propriétés de votre classe "user" seront remplies automatiquement à chaque fetch (la méthode magique __set() fonctionne). Voici un exemple :

Code PHP :
<?php 
// On créé une classe de base
class user {
public
$id;
public
$nom;

public function
direNom() {
echo
'Je suis ' . $this->nom;
}
}

// On se connecte
$pdo = new PDO('mysql:dbname=mabase;host=127.0.0.1', 'root', 'password');

// On execute une requête
$sql = 'SELECT id, nom FROM users';
$result = $pdo->query($sql);

// On choisi le mode de distribution
$result->setFetchMode(PDO::FETCH_CLASS, 'user');

// On prends la première ligne
// Notez qu'il n'est plus nécessaire d'indiquer le type de fetch
$utilisateur = $result->fetch();

// On affiche le nom
// Ceci affichera par exemple "Je suis Ekilio"
$utilisateur->direNom();

Il existe une autre variante du type CLASS, la constante PDO::FETCH_CLASSTYPE. Cette constante va fonctionner globalement comme la précédente, à ceci près que le nom de la classe à créer ne doit pas être spécifié par setFetchMode : il sera directement récupéré dans la première colonne du résultat.

Enfin, la troisième constante est la constante PDO::FETCH_INTO ; elle fonctionne globalement comme FETCH_CLASS sauf qu'elle met à jour le même objet à chaque fetch() au lieu d'en créer un nouveau à chaque fois.

2) La fonction fetchAll()

Une seconde façon d'utiliser le résultat est de faire appel à la fonction fetchAll(). Cette fonction interviendra exactement de la même manière que fetch(), et prends les mêmes arguments, mais renvoi la totalité des résultats sous forme d'un tableau de résultats du type que vous aurez défini. Voici un exemple :

Code PHP :
<?php 
// On se connecte
$pdo = new PDO('mysql:dbname=mabase;host=127.0.0.1', 'root', 'password');

// On execute une requête
$sql = 'SELECT id, nom FROM users';
$result = $pdo->query($sql);

// On choisi le type de résultat (parce que j'ai
// la flemme de les taper tous)
$result->setFetchMode(PDO::FETCH_ASSOC);

// Et on fetch fetch fetch ce $result qui nous plait...
// (Pardon, il est tard)
$tableau = $result->fetchAll();
print_r($tableau);

// Ceci affichera :
// Array (
// [0] => Array (
// [ID] => 1,
// [NOM] => Ekilio
// )
// [1] => Array (
// [ID] => 2,
// [NAME] => SephiChan
// )
// )

3) Par foreach()

Enfin, la troisième méthode pour parcourir les résultats est d'utiliser la fonction foreach, directement sur notre objet de résultats, comme ceci :

Code PHP :
<?php 
// On se connecte
$pdo = new PDO('mysql:dbname=mabase;host=127.0.0.1', 'root', 'password');

// On execute une requête
$sql = 'SELECT id, nom FROM users';
$result = $pdo->query($sql);

// On choisi le type de résultat (parce que j'ai
// la flemme de les taper tous)
$result->setFetchMode(PDO::FETCH_ASSOC);

// On affiche tout
foreach($result as $tableau) {
echo
"{$tableau['id']} => {$tableau['nom']}\n";
}

// Ceci donnera quelque chose de ce genre :
// 1 => Ekilio
// 2 => SephiChan

Il existe une quatrième méthode pour récupérer les résultats, mais nous nous y intéresserons plus tard.

VI/ Le commit et les transactions

Théorie générale

D'abord, un peu de théorie. Une transaction, c'est un système qui permet de demander à MySQL de considérer un ensemble de requêtes comme un "bloc", qui doit s'executer en entier ou pas du tout.

Prenons un exemple pratique : imaginons un jeu dans lequel nos joueurs ont un système d'équipement. Ils peuvent donc vouloir équiper un objet depuis leurs inventaire. Si il le font, cela correspondrait aux requêtes suivantes :

- Suppression de l'objet de l'inventaire
- Ajout de l'objet dans l'équipement
- Mise à jour des statistiques du joueur

Imaginons maintenant que la seconde requête plante. Dans ce cas, soit le joueur voit l'objet disparaitre mais ses stats être tout de même améliorées, soit (pire) il le voit disparaitre sans amélioration. Dans les deux cas, il perd son objet, ce qui n'était pas prévu. Le principe des transactions est justement là pour remédier à ça !

Comment ça marche ? C'est simple ! On utilise deux termes, le "commit" et le "rollback". Le commit veux dire "effectuer toutes les modifications des requêtes précédentes" ; et le rollback veux dire "annuler toutes les modifications des requêtes précédentes". En d'autre termes, cela donnerais cela :

Code :
DEBUT DE TRANSACTION
EXECUTER suppression_de_l_objet
SI rate ROLLBACK
SINON EXECUTER ajout_de_l_object
SI rate ROLLBACK
SINON EXECUTER changement_des_stats
SI rate ROLLBACK
SINON COMMIT

Et là, si l'un des requêtes échoue, les changements seront totalement annulés, comme si rien ne s'était produit ; et sinon, ils s'effectueront. Notez au passage qu'il était possible en mysql_* d'utiliser les transactions ; simplement, il fallait les gérer à la main.

Pratique dans PDO

PDO propose un système bien plus pratique pour gérer les transactions : les trois fonctions beginTransaction(), commit() et rollBack(). Lorsqu'on ne les utilise pas, certains SGBD (dont MySQL) ont un mode "autocommit", c'est à dire qu'ils font un commit après chaque requête ; néanmoins, ce mode plante un peu (en tous cas chez moi) donc je vous suggère fortement d'utiliser ces fonctions.

Reprenons le pseudo-code précédent et utilisons-le en version PDO :

Code PHP :
<?php 
// On commence par lancer la transaction
$pdo->beginTransaction();

// On execute la première requête
$pdo->query('DELETE FROM inventaire WHERE id = ' . $id);

// On vérifie
if($pdo->errorInfo()[1]) {

// Il y a eu une erreur : on annule
$pdo->rollBack();
} else {

// On execute la seconde requête
$pdo->query('INSERT INTO equipement (objet) VALUES (' . $id . ')');

// On vérifie à nouveau
if($pdo->errorInfo()[1]) {

// On annule
$pdo->rollBack();
} else {

// On execute la troisième requête
$pdo->query('UPDATE stats...');

// On vérifie une troisième fois
if($pdo->errorInfo()[1]) {
$pdo->rollBack();
} else {
// On effectue réellement les requêtes
$pdo->commit();
}
}
}

Notez qu'avant le commit(), aucune modification n'est réellement apportée à la base de données ; si nous avions placé un die() avant celui-ci, la base n'aurait pas été modifiée du tout.

VII/ Les requêtes préparées

Allez, abordons maintenant le gros morceau : les requêtes préparées ! Ce sont elles qui font la véritable force de PDO et son utilité principale.

Un peu de théorie

Pour commencer, revoyons rapidement le principe des requêtes préparées. Vous connaissez, j'imagine, le principe du MVC et celui selon lequel il faut séparer le code de l'affichage ; et bien, ici, c'est un peu la même chose, on veux séparer le code des données.

N'oublions pas que les SGBD sont fait essentiellement pour stoquer et restituer des données ; et que SQL n'est qu'une façon de leur indiquer la manière dont on souhaite que ces données soient stoquées ou restituées. Il est donc logique d'imaginer une séparation stricte : d'un coté, le code SQL pour dire ce que l'on souhaite faire, et de l'autre, les données que l'on souhaite voir traiter avec ce code.

Les requêtes préparées ont deux avantages principaux. Tout d'abord, parce qu'on sépare strictement code et données, il est impossible de faire passer des données pour du code (ce qui était le principe des injections SQL) ; et de ce fait, il n'est pas nécessaire de s'inquiéter de la sécurité des requêtes. Ensuite, cette séparation permet une mise en cache par le moteur du code : il a été interprété une fois, et même si on souhaite l'executer pour trente données différentes, il ne sera toujours interprété qu'une seule fois. Gain de temps, de performances, bref, l'extase.

Note : Mysql dans ses version antérieurs à la 4.1 ne supporte pas nativement les requêtes préparées ; PDO émule dans ce cas ces requêtes, et vous pouvez donc les utiliser tout de même, bien que le gain de temps sera moindre.

Application en SQL

Rapidement, à quoi ressemble une requête préparée en SQL ? Il y a deux méthodes. La plus simple consiste à utiliser des ? à la place des données, comme ceci :

Code :
INSERT INTO user (id, nom) VALUES (?, ?)

Cette syntaxe à l'avantage de la rapidité d'écrite... et l'inconvénient d'être totalement impossible à maintenir sur le long terme, car on se réfère alors aux ? dans l'ordre, et donc en cas de changement, la requête tombe à l'eau.

La seconde méthode consiste à nommer des variables avec la syntaxe :variable pour indiquer laquel nous interesse, comme ceci :

Code :
INSERT INTO user(id, nom) VALUES (:id, :nom)

Dans ce cas, il ne nous restera plus qu'à indiquer à notre moteur à quoi correspond :id et :nom, et l'execution se fera. Cette syntaxe est plus lisible et surtout beaucoup plus simple à maintenir ; c'est celle que j'utiliserais dans ce tutoriel.

Note : Certains SGBD supporte l'une des deux syntaxes, et pas l'autre. Il n'est pas nécessaire de vous en soucier : PDO utilisera automatiquement le type le plus approprié, que vous utilisiez l'un ou l'autre.

Application en PDO

La création et l'execution de requêtes préparées en PDO se fait en deux étapes : tout d'abord, on prépare la requêtes ; puis on l'execute en passant les données à utiliser.

La première partie, la création, se fait via la fonction prepare() et retourne un objet de type PDOStatement, que nous avons déjà vu précédement pour les résultats. La seconde partie se fait via la méthode execute() de notre objet PDOStatement, qui prends en paramètre un tableau associatif clef => valeur pour les différents noms dans la requête.

Voici un exemple :

Code PHP :
<?php 
// On prépare une requête
$stmt = $pdo->prepare('DELETE FROM users');

// On l'execute
$stmt->execute();

// Passer par une requête préparée pour une requête sans paramètres
// n'est utile que si on souhaite executer plusieurs fois la requête,
// comme ceci :
$stmt->execute();

// On prépare une autre requête
$stmt2 = $pdo->prepare('INSERT INTO users (nom) VALUES (:id, :nom)');

// On l'execute en lui passant les paramètres
// Attention : la requête plantera si le nombre ou le nom de clefs dans le tableau ne correspond pas
$stmt2->execute(array('id' => 2, 'nom' => 'Ekilio'));

// Ainsi, ces requêtes auraient plantées :
// $stmt2->execute(array('essai' => 2, 'nom' => 'Ekilio'));
// $stmt2->execute(array('nom' => 'Ekilio'));
// En revanche, l'ordre n'a pas d'importance (il en aurait eu avec les ?)

Et voila ! Ce n'était pas difficile, n'est-ce pas ?

VIII/ Les binds

Il existe une autre méthode pour attribuer des valeurs ou les récupérer dans le résultat : les binds. Le principe est de ne plus passer par un intermédiaire (tableau ou autre) mais directement d'associer une variable ou une valeur à une partie de la requête.

Binder un paramètre à une valeur

La première utilité de ceci est la plus simple : on remplace l'utilisation du tableau associatif de la fonction execute() par une utilisation directe. Autrement dit, au lieu de faire :

Code PHP :
<?php 
// On prépare une autre requête
$stmt = $pdo->prepare('INSERT INTO users (nom) VALUES (:id, :nom)');

// On l'execute en lui passant les paramètres
$stmt->execute(array('id' => 2, 'nom' => 'Ekilio'));

On peut utiliser la méthode bindValue() de l'objet PDOStatment pour associer une valeur, comme ceci :

Code PHP :
<?php 
// On prépare une autre requête
$stmt = $pdo->prepare('INSERT INTO users (nom) VALUES (:id, :nom)');

// On associe les valeurs
$stmt->bindValue('id', 2);
$stmt->bindValue('nom', 'Ekilio');

// On l'execute sans lui passer de paramètres cette fois
$stmt->execute();

Cette méthode vous permet de ne pas avoir à définir tous vos paramètres en même temps.

Binder un paramètre à une variable

La seconde méthode est encore plus pratique pour certaines applications. Le principe va être de passer en paramètre une variable (qui sera récupérée par référence, toujours) et de l'associer complètement à un paramètre de la requête. Ainsi, si la variable change, la valeur du paramètre changera également, sans avoir à executer d'autres instruction. Cela se fait via la méthode bindParam() de l'objet PDOStatement. Voici l'exemple :

Code PHP :
<?php 
// On prépare une autre requête
$stmt = $pdo->prepare('INSERT INTO users (nom) VALUES (:id, :nom)');

// On prépare nos variables
$nom = 'Ekilio';
$id = 1;

// On les associe
$stmt->bindParam('id', $id);
$stmt->bindParam('nom', $nom);

// On execute
// Ceci va insérer dans la table une ligne avec comme id 1 et comme nom Ekilio
$stmt->execute();

// On change les variables
$nom = 'SephiChan';
$id = 2;

// On execute à nouveau
// Ceci va insérer dans la table une ligne avec comme id 2 et comme nom SephiChan
// Notez qu'il est inutile d'executer des commandes sur $stmt : la modification de
// la variable suffit
$stmt->execute();

Binder un champ de résultat à une variable

La troisième utilisation du bind est aussi une manière supplémentaire de récupérer des résultats : vous pouvez directement associer un champs à une variable. C'est le même principe que pour binder une variable à un paramètre, mais à l'envers : cette fois, chaque fetch du résultat se traduira par une modification de la variable. Cela se fait par le biais de la méthode bindColumn() de l'objet PDOStatement, et voici l'exemple :

Code PHP :
<?php 
// On prépare la requête
$stmt = $pdo->prepare('SELECT id, nom FROM users');

// On execute la requête
$stmt->execute();

// On associe les variables
// Notez qu'on peut associer les variables soit par nom de colonne, soit par numéro
$stmt->bindColumn(1, $id);
$stmt->bindColumn('nom', $nom);

// On fetch une première fois
// Notez le paramètre a appliquer au fetch
$stmt->fetch(PDO::FETCH_BOUND);

// On affiche
echo "#$id : $nom"; // Affichera : #1 : Ekilio

// On refetch
$stmt->fetch(PDO::FETCH_BOUND);

// On ré-affiche
echo "#$id : $nom"; // Affichera : #2 : SephiChan

// Notez qu'ici aussi, il n'est pas nécessaire de faire plus d'opération que le fetch ! Les variables sont directement changées.

La suite au prochain épisode !


RE: PDO : Comment ça marche - Ter Rowan - 22-01-2010

dommage que tu ne l'ais pas fait y a trois mois ^^ quand je cherchais à passer à pdo :p

concernant les transactions, ta solution des if pour le roll back me gène un peu. En effet si on a une succession de requêtes, le code aura un nombre de if imbriqué trop important (donc moins lisible/maintenable)

Ne pourrait on pas plutôt utiliser les exceptions dans ce cas du genre

try
{
requete 1
requete 2
requete 3
....
requete n
commit
}
catch(e)
{
rollback
traitement de (e)
}

ainsi, je pense (mais bon pas vraiment habitué à try catch) que si requete 3 plante et génère une erreur, on aura le roll back pour les requetes 1 et 2 et ce sans n if de partout imbriqué Smile


RE: PDO : Comment ça marche - Ekilio - 22-01-2010

C'est tout à fait vrai Smile Mais mon tuto se veut tourner vers PDO et ses fonctionnalités plus que vers le code en général. Il y a plusieurs exemples qui ne sont pas pratiques ou pas adaptés à la réalité, mais qui servent pour montrer une fonctionnalité Smile

Le tuto n'est pas tout à fait fini, la suite sera cet aprem je pense !


RE: PDO : Comment ça marche - Zamentur - 22-01-2010

Concernant les requêtes préparées, est ce qu'il y a une erreur si on passe un argument de type chaine de caractère à une clef qui devrait recevoir un entier?
Par exemple si on passe une chaine vide est ce que ce sera convertit en 0?

Je pose la question car je n'utilise pas PDO, j'ai une classe d'abstraction sql qui gère ces problématiques et même d'autres, cependant j'envisage d'écrire un pilote PDO pour la compatibilité php6.

En tout cas très bon tuto.


RE: PDO : Comment ça marche - custmax - 22-01-2010

Super ! Ca me permet de découvrir PDO, depuis le temps que je me dis d'apprendre.

Merci pour ce tuto ! (en attendant la suite ^^)


RE: PDO : Comment ça marche - Mysterarts - 23-01-2010

Merci à toi pour ce tuto, je me préparais justement à m'y mettre !
C'est chose faite grâce à ce topic qui m'a permis d'y mettre un pied : reste plus qu'à appliquer.
(Bah oui, je traine, je sais...)

Mysterarts


RE: PDO : Comment ça marche - Sephi-Chan - 23-01-2010

Merci Ekilio pour ces ressources !
Je me réjouis de voir autant de discussions à propos de PDO ces derniers temps.


Sephi-Chan


RE: PDO : Comment ça marche - Ekilio - 25-01-2010

Pour répondre à Zamentur : de ce que j'ai vu, il y a une conversion faite si le type attendu n'est pas le bon (par exemple, la table attends un entier et c'est un string qui est entré).

Au passage, il existe également un troisième paramètre aux deux options de bind (bindValue et bindParam) qui est le $data_type, et qui permet de forcer un type particulier de données. Il prend comme valeur une des constantes suivantes :

PDO:TongueARAM_BOOL
PDO:TongueARAM_NULL
PDO:TongueARAM_INT
PDO:TongueARAM_STR
PDO:TongueARAM_LOB (Représente un objet de type "large" en SQL, comme le contenu d'un champs de type blob par exemple)
PDO:TongueARAM_STMT (Représente un jeu de résultat d'une autre requête préparée, n'est pas supporté par tous les moteurs - aucune idée si MySQL le supporte ou pas)
PDO:TongueARAM_INPUT_OUTPUT (Je me contente de copier la doc vu que je ne comprends pas parfaitement ce paramètre : Spécifie que le paramètre est un paramètre INOUT pour une procédure stockée. Vous devez utiliser l'opérateur OR avec un type de données explicite PDO:TongueARAM_*. )

Sinon, la fin du tuto (il manque encore une partie) ce soir ou demain je pense


RE: PDO : Comment ça marche - Joojo - 02-03-2010

Dans plusieurs scripts et tuto sur la PDO, ils utilisent la fonction closeCursor() après chaque requête, utile ou pas? A ce que j'ai lu cela évite des erreurs et "libère la connexion du serveur, permettant ainsi à d'autres requêtes SQL d'être exécutées, mais quitte la requête, permettant ainsi qu'elle soit de nouveau exécutée".

http://www.manuelphp.com/php/function.pdostatement-closecursor.php


RE: PDO : Comment ça marche - Freygolow - 07-06-2010

Salut,
J'ai effectué quelques tests de performances qui ne sont pas cohérents avec ce qui a été dit.
Il est dit (ici et partout sur le net) que le paramètre de fetch par défaut est PDO::FETCH_BOTH or les résultats que je trouvent diffèrent:

Tests effectués sur plus de 20000 enregistrements:
fetch(): page génerée en 60ms
fetch(PDO::FETCH_BOTH): page générée en 72ms
fetch(PDO::FETCH_ASSOC): page génerée en 64ms

En revanche avec fetchAll, le résultat est cohérent.

Je trouve que la différence est quand même élevée.
Quelqu'un aurait une réponse à ce mystère? :p

PS:
Même l'espace mémoire utilisée diffère entre un fetch(PDO::FETCH_BOTH) et un fetch()