PDO – Procédures préparées et stockées

Procédures préparées et procédures stockées

Nombre de bases de données supportent le concept de procédures préparées. Quelles sont-elles? 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 paramètres variables. Les requêtes préparées offrent deux grands avantages:

  • La requête ne doit être analysée (ou préparée)qu’une 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 sa structure pour exécuter la requête. Pour les requêtes complexes, ce processus peut prendre assez de temps et peut donc ralentir vos applications si vous avez besoin de 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 les « analyser » / « compiler » / « optimiser » du cycle. En bref, les requêtes préparées utilisent moins de ressources et s’exécutent plus rapidement.
  • Les paramètres pour les requêtes préparées n’ont pas besoin d’être entre guillemets, le pilote le gère pour vous. Si votre application utilise exclusivement les requêtes préparées, vous pouvez être sûr qu’aucune injection SQL ne va se produire. (Cependant, si vous construisez d’autres parties de la requête en vous basant sur des entrées utilisateurs, vous courrez toujours un risque).

Les requêtes préparées sont si utiles qu’elles sont l’unique fonctionnalité que PDO émule pour les pilotes qui ne les supportent pas. Cela garantit que vous serez capable d’utiliser la même technique pour accéder aux données sans vous soucier des capacités de la base de données.

Exemple#6 Insertions répétées utilisant des requêtes préparées

Cet exemple effectue une requête INSERT en y substituant un nom et une valeur pour les champs nommés.

$stmt = $dbh->prepare(« INSERT INTO REGISTRY (name, value) VALUES (:name, :value) »);$stmt->bindParam(‘:name’, $name);

$stmt->bindParam(‘:value’, $value);

// insert une ligne

$name = ’one’;

$value = 1;

$stmt->execute();

// insert une autre ligne avec des valeurs différentes

$name = ’two’;

$value = 2;

$stmt->execute();

Exemple#7 Insertions répétées à l’aide des requêtes préparées

Cet exemple effectue une requête INSERT en y substituant un nom et une valeur pour les variables, notées « ?« .

$stmt = $dbh->prepare(« INSERT INTO REGISTRY (name, value) VALUES (?, ?) »);$stmt->bindParam(1, $name);

$stmt->bindParam(2, $value);

// insert une ligne

$name = ’one’;

$value = 1;

$stmt->execute();

// insert une autre ligne avec des valeurs différentes

$name = ’two’;

$value = 2;

$stmt->execute();

Exemple#8 Récupération des données en utilisant les requêtes préparées

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 ainsi aucun risque d’attaque par injection SQL.

$stmt = $dbh->prepare(« SELECT * FROM REGISTRY where name = ? »);if ($stmt->execute(array($_GET['name']))) {

while ($row = $stmt->fetch()) {

print_r($row);

}

}

Si le pilote de base de données le supporte, vous pourrez relier des paramètres aussi bien en sortie qu’en entrée. Les paramètres de sortie sont utilisés typiquement pour récupérer les valeurs d’une procédure stockée. Ils sont un peu plus complexes à utiliser que les paramètres d’entrée, car vous devez savoir quelle longueur un paramètre donné pourra atteindre lorsque vous le liez. Si la valeur retournée est plus grande que la taille que vous avez suggérée, une erreur sera soulevée.

Exemple#9 Appel d’une procédure stockée avec un paramètre de sortie

$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  »procedure returned $return_value\n »;

Vous pouvez également spécifier les paramètres qui gèrent les valeurs d’entrée et de sortie, la syntaxe est similaire aux paramètres de sortie. Dans l’exemple suivant, la chaîne ‘hello’ est passée à la procédure stockée et lorsque celle-ci s’exécute , ‘hello’ est remplacé par la valeur de retour de la procédure.

Exemple#10 Appel d’une procédure stockée avec un paramètre entrée / sortie

$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  »procedure returned $value\n »;

Exemple#11 Utilisation invalide de marqueur

$stmt = $dbh->prepare(« SELECT * FROM REGISTRY where name LIKE ’%?%’ »);$stmt->execute(array($_GET['name']));

// La variable doit être utilisée à la place de la valeur principale

$stmt = $dbh->prepare(« SELECT * FROM REGISTRY where name LIKE ? »);

$stmt->execute(array(« %$_GET[name]% »));