mirror of
https://github.com/macintoshplus/doc-fr.git
synced 2026-03-26 01:42:09 +01:00
216 lines
7.0 KiB
XML
216 lines
7.0 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 84e8f0960b841a5ebca9d81cd2c2311b6504a371 Maintainer: yannick Status: ready -->
|
|
<!-- Reviewed: yes -->
|
|
|
|
<chapter xml:id="pdo.prepared-statements" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Requêtes préparées et procédures stockées</title>
|
|
<para>
|
|
La plupart des bases de données supportent le concept des requêtes préparées.
|
|
Qu'est-ce donc ? Vous pouvez les voir comme une sorte de modèle compilé
|
|
pour le SQL que vous voulez exécuter, qui peut être personnalisé en utilisant
|
|
des variables en guise de paramètres. Les requêtes préparées offrent
|
|
deux fonctionnalités essentielles :
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
La requête ne doit être analysée (ou préparée) qu'une seule fois, mais peut
|
|
être exécutée plusieurs fois avec des paramètres identiques ou différents.
|
|
Lorsque la requête est préparée, la base de données va analyser, compiler
|
|
et optimiser son plan pour exécuter la requête. Pour les requêtes complexes,
|
|
ce processus peut prendre assez de temps, ce qui peut ralentir vos applications
|
|
si vous devez répéter la même requête plusieurs fois avec différents paramètres.
|
|
En utilisant les requêtes préparées, vous évitez ainsi de répéter le cycle
|
|
analyse/compilation/optimisation. Pour résumer, les requêtes préparées
|
|
utilisent moins de ressources et s'exécutent plus rapidement.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Les paramètres pour préparer les requêtes n'ont pas besoin d'être entre
|
|
guillemets ; le pilote gère cela pour vous. Si votre application utilise exclusivement
|
|
les requêtes préparées, vous pouvez être sûr qu'aucune injection SQL
|
|
n'est possible (Cependant, si vous construisez d'autres parties de la requête
|
|
en vous basant sur des entrées utilisateurs, vous continuez à prendre un risque).
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>
|
|
Les requêtes préparées sont tellement pratiques que c'est l'unique fonctionnalité
|
|
que PDO émule pour les pilotes qui ne les prennent pas en charge. Ceci assure de pouvoir
|
|
utiliser la même technique pour accéder aux données, sans se soucier des capacités
|
|
de la base de données.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Insertions répétitives en utilisant les requêtes préparées</title>
|
|
<simpara>
|
|
Cet exemple effectue une requête INSERT en y substituant un
|
|
<literal>nom</literal> et une <literal>valeur</literal> pour les marqueurs nommés.
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
|
|
$stmt->bindParam(':name', $name);
|
|
$stmt->bindParam(':value', $value);
|
|
|
|
// insertion d'une ligne
|
|
$name = 'one';
|
|
$value = 1;
|
|
$stmt->execute();
|
|
|
|
// insertion d'une autre ligne avec des valeurs différentes
|
|
$name = 'two';
|
|
$value = 2;
|
|
$stmt->execute();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Insertions répétées en utilisant des requêtes préparées</title>
|
|
<simpara>
|
|
Cet exemple effectue une requête INSERT en y substituant un <literal>nom</literal>
|
|
et une <literal>valeur</literal> pour les marqueurs <literal>?</literal>.
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
|
|
$stmt->bindParam(1, $name);
|
|
$stmt->bindParam(2, $value);
|
|
|
|
// insertion d'une ligne
|
|
$name = 'one';
|
|
$value = 1;
|
|
$stmt->execute();
|
|
|
|
// insertion d'une autre ligne avec différentes valeurs
|
|
$name = 'two';
|
|
$value = 2;
|
|
$stmt->execute();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Récupération des données en utilisant des requêtes préparées</title>
|
|
<simpara>
|
|
Cet exemple récupère des données basées sur la valeur d'une clé fournie
|
|
par un formulaire. L'entrée utilisateur est automatiquement échappée, il n'y a
|
|
donc aucun risque d'attaque par injection SQL.
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
|
|
$stmt->execute([$_GET['name']]);
|
|
foreach ($stmt as $row) {
|
|
print_r($row);
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
<example>
|
|
<title>Appel d'une procédure stockée avec un paramètre de sortie</title>
|
|
<simpara>
|
|
Si le pilote de la base de données le prend en charge, vous pouvez également lier
|
|
des paramètres aussi bien pour l'entrée que pour la sortie. Les paramètres de sortie
|
|
sont utilisés typiquement pour récupérer les valeurs d'une procédure stockée.
|
|
Les paramètres de sortie sont un peu plus complexes à utiliser que les paramètres d'entrée
|
|
car vous devez savoir la longueur qu'un paramètre donné pourra atteindre lorsque vous
|
|
le liez. Si la valeur retournée est plus longue que la taille qui vous aurez suggéré,
|
|
une erreur sera émise.
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$stmt = $dbh->prepare("CALL sp_returns_string(?)");
|
|
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000);
|
|
|
|
// Appel de la procédure stockée
|
|
$stmt->execute();
|
|
|
|
print "La procédure a retourné : $return_value\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
<example>
|
|
<title>Appel d'une procédure stockée avec un paramètre d'entrée/sortie</title>
|
|
<simpara>
|
|
Vous devez également spécifier les paramètres qui gèrent les valeurs
|
|
aussi bien pour l'entrée que pour la sortie ; la syntaxe est similaire aux
|
|
paramètres de sortie. Dans le prochain exemple, la chaîne 'Bonjour' est passée
|
|
à la procédure stockée et lorsqu'elle retourne la valeur, 'Bonjour' est remplacée
|
|
par la valeur retournée par la procédure.
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
|
|
$value = 'hello';
|
|
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
|
|
|
|
// appel de la procédure stockée
|
|
$stmt->execute();
|
|
|
|
print "La procédure a retourné : $value\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Utilisation invalide de marqueur</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
|
|
$stmt->execute([$_GET['name']]);
|
|
|
|
// un marqueur doit être utilisé à la place d'une valeur complète
|
|
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
|
|
$stmt->execute(["%$_GET[name]%"]);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|