samedi 23 mars 2013

Les requètes préparées

Voilà la toute puissance de PDO... Les fameuses requètes préparées. Réutilisables, plus sûr, plus classe.
Le principe est simple, vous n'allez pas exécuter directement les requètes, vous allez définir un gabarit de requète avec des "options".
Par exemple plutot que de dire "Supprimer l'enregistrement numéro 1", vous aller préparer la requète avant "Supprimer l'enregistrement numéro %onVerraApres%", ensuite dès que vous avez besoin de supprimer un enregistrement avec la requète préparée, vous aller executer la requète préparée en lui précisant au moment de l'execution quel sont les valeurs à utiliser.

Paramètres mystères

Il y a 2 façon de définir une requète préparée, la première utilise le caractère ? pour transmettre des valeurs au moment de l'execution, concrètement ça ressemble à ça :
?
1
2
3
4
5
6
7
8
9
10
11
12
13
// Préparation de la requète
$selectionPrepa = $connection->prepare('SELECT * FROM createurs WHERE id=? LIMIT 1');
try {
  // On envois la requète
  $selectionPrepa->execute(array(1));
   
  // Traitement
  if( $enregistrement = $selectionPrepa->fetch(PDO::FETCH_OBJ)){
    echo '<h1>', $enregistrement->nom, ' ', $enregistrement->prenom,  '</h1>';
  }
} catch( Exception $e ){
  echo 'Erreur de suppression : ', $e->getMessage();
}
Ce système permet de réutiliser la requète préparée par la suite en modifiant la valeur utilisée lors de l'execution par une autre.
On peut biensûr définir plusieurs paramètres mystères :
?
1
2
3
4
5
6
7
8
9
10
11
12
13
$selectionPrepa = $connection->prepare('SELECT * FROM createurs WHERE YEAR(date_naiss)=? AND nationalite=?');
try {
  // On envois la requète
  $selectionPrepa->execute(array(1925, 'fr'));
   
  // Traitement
  while( $enregistrement = $selectionPrepa->fetch(PDO::FETCH_OBJ)){
    echo '<h1>', $enregistrement->nom, ' ', $enregistrement->prenom,  '</h1>';
  }
   
} catch( Exception $e ){
  echo 'Erreur de requète : ', $e->getMessage();
}
Les paramètres sont utilisées dans l'ordre d'apparition dans la requète.

Paramètres nommés

Supposons maintenant que nous ayons beaucoup de paramètres (ou des paramètres que nous voudrions utiliser plusieurs fois). Vous pouvez alors utiliser les paramètres nommées.
Premier cas, un paramètre utilisé plusieurs fois :
?
1
2
3
4
5
6
7
8
9
10
11
12
13
$selectionPrepa = $connection->prepare('SELECT * FROM createurs WHERE nom LIKE :search OR prenom LIKE :search;
try {
  // On envois la requète
  $selectionPrepa->execute(array('search'=>'%gi%'));
   
  // Traitement
  while( $enregistrement = $selectionPrepa->fetch(PDO::FETCH_OBJ)){
    echo '<h1>', $enregistrement->nom, ' ', $enregistrement->prenom,  '</h1>';
  }
   
} catch( Exception $e ){
  echo 'Erreur de requète : ', $e->getMessage();
}
Autre cas, beaucoup de paramètres :
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$insert = $connection->prepare('INSERT INTO createurs VALUES(
NULL, :nom, :prenom, :date_naiss, :date_mort, :nationalite, :pseudo)');
try {
  // On envois la requète
  $success = $insert->execute(array(
    'nom'=>'Dus',
    'prenom'=>'Jean-Claude',
    'date_naiss'=>date('Y-m-d'),
    'date_mort'=>NULL,
    'nationalite'=>'fr',
    'pseudo'=>NULL
  ));
   
  if( $success ) {
    echo "Enregistrement réussi";
  
} catch( Exception $e ){
  echo 'Erreur de requète : ', $e->getMessage();
}
Au moment de l'execution, vous transmettez un tableau indexé avec les clefs portant le nom des paramètres nommés (sans le 2 points).
Les données transmise peuvent provenir de variables :P
PDO se chargera automatiquement des échapements et des formats de transmission. Mais vous pouvez allé plus loin en utilisant la méthode bindParam :)

Paramètres Bindés

La méthode bindParam() permet de remplir la requète préparée avec le contenu d'une variable, on a également la possibilité de préciser un type de donnée et une taille.
Important : L'utilisation de bindParam est très puissante, vous pouvez préparer votre requète bien avant l'envois et la rééxécuter plusieurs fois, si des changements ont lieu dans les variables bindées, elle seront prises en compte au moment de l'exécution.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$insert = $connection->prepare('INSERT INTO createurs VALUES(
NULL, :nom, :prenom, :date_naiss, :date_mort, :nationalite, :pseudo)');
try {
  // On rempli les paramètres
  $insert->bindParam(':nom', $nom, PDO::PARAM_STR, 100);
  $insert->bindParam(':prenom', $prenom, PDO::PARAM_STR, 100);
  $insert->bindParam(':date_naiss', date('Y-m-d'));
  $insert->bindParam(':nationalite, $nationalite, PDO::PARAM_STR, 2);
  $insert->bindParam(':pseudo', $pseudo, PDO::PARAM_STR);
   
  // On exécute
  $insert->execute();
 
  if( $success ) {
    echo "Enregistrement réussi";
  
} catch( Exception $e ){
  echo 'Erreur de requète : ', $e->getMessage();
}
La méthode bindParam() a une petite soeur : bindValue(). Cette méthode est une version light de bindParam() qui présente l'avantage de proposer de contrôle des données transmises à la requète préparée.

Aucun commentaire:

Enregistrer un commentaire