il utilise quel pilote PDO dans son code ?
MySql bien sur mais avec un "objet" nous sommes d'accord , c'est PDO qui a maché le travail tu en conviendras j'espéres![]()
Mode par défaut (émulation de requête préparé, donc un simple query au final)
Résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 $dbh = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root'); $stmt = $dbh->prepare('SELECT * FROM `exemple` WHERE `id` > :id'); $stmt->execute(array('id' => 1)); var_dump( $stmt->getAttribute(PDO::ATTR_EMULATE_PREPARES), $stmt->fetchAll() );
Log mysql :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 bool(true) array(1) { [0]=> array(4) { ["id"]=> string(1) "2" [0]=> string(1) "2" ["var"]=> string(4) "truc" [1]=> string(4) "truc" } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3Connect root@localhost on test Query SELECT * FROM `exemple` WHERE `id` > '1' Quit
Mode sans émulation (vrai requête préparée)
Résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 $dbh = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root'); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $stmt = $dbh->prepare('SELECT * FROM `exemple` WHERE `id` > :id'); $stmt->execute(array('id' => 1)); var_dump( $stmt->getAttribute(PDO::ATTR_EMULATE_PREPARES), $stmt->fetchAll() );
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 bool(false) array(1) { [0]=> array(4) { ["id"]=> int(2) [0]=> int(2) ["var"]=> string(4) "truc" [1]=> string(4) "truc" } }
Log Mysql :
On voit bien la différence (et encore les logs humanise la lecture), de plus le résultats est casté (mais uniquement si on utilise les marqueurs nommés)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4Connect root@localhost on test Prepare SELECT * FROM `exemple` WHERE `id` > ? Execute SELECT * FROM `exemple` WHERE `id` > '1' Close stmt
Je ne crois pas que nous trolons, car c'est vraiment 100% le sujet et il n'est pas clos, mais avant tout tu m'a mis le doute, et pourtant je crois avoir du savoir et du sérieux. Chapeau a toi d'avoir insisté, au moins ceux qui auront suivi auront un vrais TOPO sur un aspect trés peut traité sérieusement.
Donc Bravo et Merci.
Je pousses le bouchon d'un cran, je ne remarques que deux failles
en mode client-side , la premiére reste un vrais mystére car il mets des '' autour des numériques, et ça me contrarie, surtout qu'en fait il trouve le bon datac' est totalement un mystére.
Autre point ce serait pénalisant d'avoir deux appels réels a MySql que un non ?
Bref tu m'auras empéché de dormir ... et demain heu... ce matin je replongerais ssur le sujet.![]()
le execute est assez générique, mais tu peux faire avec avec les bind,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 $stmt = $dbh->prepare('SELECT * FROM `exemple` WHERE `id` > :id'); $stmt->bindValue(':id', 1, PDO::PARAM_INT); $stmt->execute();
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3Connect root@localhost on test Query SELECT * FROM `exemple` WHERE `id` > 1 Quit
la plupart du temps on fait qu'un seul SELECT donc inutile de faire une requêtes préparées, ca devient intéressant en cas d'INSERT multiple, puisque on va créée le template (prepare) et ensuite seuls les paramètres seront fournis
pas préparé (query ou en émuler)
en préparé (prépare + émule a false)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 INSERT INTO test SET id=1, var=1 INSERT INTO test SET id=2, var=2 INSERT INTO test SET id=3, var=3 INSERT INTO test SET id=4, var=4 INSERT INTO test SET id=5, var=5 ... INSERT INTO test SET id=N, var=N
plus la requête est compliqué plus le gain de performance sera grand, et si tu regardes bien l'injection n'est pas possible (même si en préparé manuel on doit échappé les valeurs), puisque le EXECUTE va tout simplement échoué
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 PREPARE stmt FROM 'INSERT INTO test SET id=?, var=?' EXECUTE stmt1 USING 1, 1 EXECUTE stmt1 USING 2, 2 EXECUTE stmt1 USING 3, 3 EXECUTE stmt1 USING 4, 4 EXECUTE stmt1 USING 5, 5 ... EXECUTE stmt1 USING N, N DEALLOCATE PREPARE stmt1
si ça t’intéresse j'avais fais une fonction pour faire des requêtes préparés (des vrais) avec l'extension mysql_* :
https://github.com/stealth35/mysql_prepare
EDIT : ps la première version est plus abordable a la lecture :
https://github.com/stealth35/mysql_p...ql_prepare.php
Juste un petit rajout
Effectivement comme je l'avais déjà signaler merci pour l'info du mode émulation pour mysql par défaut qui n'est marqué nulle part dans la doc.
Ce qui est complètement débile puisque depuis php 5.3 ils ont changer la lib pdo pour mysql qui est maintenant niquel
Et donc d'ailleurs depuis php 5.3 le driver supporte parfaitement la mise en cache coté serveur des requêtes préparées ce qui est un très gros avantages en terme de performances.
J'ai refait mes tests avec le emule a false et effectivement les résultats correspondent bien mieux a ce que j'attendais et que je n'obtenais pas tout le temps.
t'as toujours possibilité le compiler PDO mysql avec la libmysql (contraiement a mysqlnd),
mais aussi y'a peu être pas forcement les droits sur PREPARE, puisque la plupart du temps il est juste recommandé de faire :
, mais bon la je suis pas sûr, je vais vérifier si en on peut quand même faire un PREPARE avec les droits là (puisque PREPARE, n'a pas l'air d’être dans le GRANT contrairement a EXECUTE)
Code : Sélectionner tout - Visualiser dans une fenêtre à part GRANT SELECT, INSERT, DELETE ON database
Partager