Table des matières
Zend_Db_Adapter
est l'API d'abstraction pour le Framework Zend.
Basé sur PDO, vous pouvez utiliser Zend_Db_Adapter
pour vous connecter sur tout les SGBD supportés,
en utilisant la même API. Les SGB supportés sont entre autres : Microsoft SQL Server, MySQL, PostgreSQL, SQLite.
Pour créer une instance de Zend_Db_Adapter
pour vous connecter à votre base de données,
vous devez appeler Zend_Db::factory()
avec le nom de l'adapteur et un tableau de paramètres
décrivant la connexion. Par exemple, pour vous connecter à une base de données MySQL appelée "camelot"
sur votre machine locale et avec le nom d'utilisateur "malory" :
<?php require_once 'Zend/Db.php'; $params = array ('host' => '127.0.0.1', 'username' => 'malory', 'password' => '******', 'dbname' => 'camelot'); $db = Zend_Db::factory('PDO_MYSQL', $params); ?>
De la même manière, pour vous connecter à une base de données SQLite appelée "camelot" :
<?php require_once 'Zend/Db.php'; $params = array ('dbname' => 'camelot'); $db = Zend_Db::factory('PDO_SQLITE', $params); ?>
Quelque soit le SGBD, vous aurez la possibilité d'utiliser exactement la même API pour interroger la base de données.
Vous devriez toujours échapper les valeurs destinées à être utilisées dans une requête SQL; cela permet de se prémunir des injections SQL.
Zend_Db_Adapter
fournies deux méthodes (via l'objet PDO) pour vous aider à échapper les valeurs.
La première est la méthode quote()
. Elle va échapper une valeur scalaire conformément aux spécificités de la base de données.
Si vous essayer d'échapper un tableau, la méthode va retourner une chaîne contenant chaque valeur du tableau, séparée par des virgules,
chacune correctement protégée (c'est pratique dans le cas de fonctions qui prennent un paramètre de type liste).
<?php // créé un objet $db, on suppose l'utilisation de MySQL // échappement d'un scalaire $value = $db->quote('St John"s Wort'); // $value is now '"St John\"s Wort"' (note the surrounding quotes) // échappement d'un tableau $value = $db->quote(array('a', 'b', 'c'); // $value vaut maintenant '"a", "b", "c"' (une chaîne séparée par des virgules) ?>
La seconde est la méthode quoteInto()
. Vous fournissez une requête de base, avec des points d'interrogations comme caractère à
remplacer, et un scalaire ou un tableau à protéger. C'est pratique pour construire rapidemant des requête et des clauses.
Les scalaires et les tableaux sont traitées de la même façon que dans la méthode quote()
.
<?php // créé un objet $db, on suppose l'utilisation de MySQL // protection d'un scalaire dans une clause WHERE $where = $db->quoteInto('id = ?', 1); // $where vaut maintenant 'id = "1"' (notez bien les guillemets supplémentaires) // protection d'un tableau dans la clause WHERE $where = $db->quoteInto('id IN(?)', array(1, 2, 3)); // $where vaut maintenant 'id IN("1", "2", "3")' (une chaîne séparée par des virgules) ?>
Une fois que vous avez une instance de Zend_Db_Adapter
, vous pouvez exécuter directement des requêtes SQL.
Zend_Db_Adapter
passe cette requête dans l'objet PDO sous-jacent, qui les prépare et les exécute, et vous retourne
ensuite une objet PDOStatement
pour que vous puissez manipuler les résultats, s'il y en a.
<?php // créé un objet $db et exécute ensuite la requête // avec une requête SQL correctement protégée $sql = $db->quoteInto( 'SELECT * FROM example WHERE date > ?', '2006-01-01' ); $result = $db->query($sql); // utilisez l'objet de type PDOStatement $result pour récupérer toutes les lignes de résultat dans un tableau $rows = $result->fetchAll(); ?>
Vous pouvez associer automatiquement vos données à la requête. Cela signifie que vous pouvez définir de multiples marqueurs de remplacement réservés et nommés dans la requête, et ensuite passer un tableau de données qui vont se substituer à ces marqueurs. Les valeurs de remplacement sont automatiquement protégées, pour prévenir les attaques par injection SQL.
<?php // créé un objet $db, et interroge la base de données. // cette fois, utilisez un marqueur de remplacement. $result = $db->query( 'SELECT * FROM example WHERE date > :placeholder', array('placeholder' => '2006-01-01') ); // utiliser le PDOStatement $result pour récupérer toutes les lignes de résultat dans un tableau $rows = $result->fetchAll(); ?>
Optionellement, vous pouvez préparer et lier manuellement une instruction SQL. Pour ce faire, utilisez la méthode prepare()
pour
obtenir un objet de type PDOStatement
, que vous pouvez manipuler directement.
<?php // créé un objet $db, et interroge la base de données. // cette fois-ci, utilisez un objet PDOStatement pour une liaison manuelle. $stmt = $db->prepare('SELECT * FROM example WHERE date > :placeholder'); $stmt->bindValue('placeholder', '2006-01-01'); $stmt->execute(); // utiliser le PDOStatement $result pour récupérer toutes les lignes de résultat dans un tableau $rows = $stmt->fetchAll(); ?>
Par défaut, PDO (and ainsi Zend_Db_Adapter
) sont en mode "auto-commit". Cela signifie que chaque requête est validée à
chaque exécution. Si vous souhaitez les exécuter à l'intérieur d'une transaction, appelez simplement la méthode beginTransaction()
vous pourrez alors valider (commit()
) ou annuler (rollBack()
) vos changements.
Zend_Db_Adapter
retourne en mode "auto-commit" jusqu'à ce que vous appeliez de nouveau beginTransaction()
.
<?php // créé une objet $db, puis débute une transaction. $db->beginTransaction(); // tente une requête // si elle réussie, validez les changements avec commit() // si elle échoue, annuler les changements avec rollback() try { $db->query(...); $db->commit(); } catch (Exception $e) { $db->rollBack(); echo $e->getMessage(); } ?>
Vous avez la possibilité d'utiliser la méthode insert()
pour créer une instruction INSERT, et lui lier les données pour l'insertion.
(Les données liées sont automatiquement protégées pour prévenir tout risque d'injection SQL).
La valeur retournée n'est pas le dernier identifiant d'insertion, la table ne contenant peut-être pas de colonne auto-incrémentée;
à la place, la valeur retournée est le nombre de lignes affectées (habituellement 1). Si vous souhaitez l'ID du dernier identifiant généré,
appelez la méthode lastInsertId()
après l'insertion.
<?php // // INSERT INTO round_table // (noble_title, first_name, favorite_color) // VALUES ("King", "Arthur", "blue"); // // créé un objet $db et ensuite... // les données des colonnes à insérer en utilisant la syntaxe nom_colonne => valeur_colonne $row = array ( 'noble_title' => 'King', 'first_name' => 'Arthur', 'favorite_color' => 'blue', ); // la table dans laquelle la ligne doit être insérée $table = 'round_table'; // insérez la ligne, et récupérez son identifiant $rows_affected = $db->insert($table, $row); $last_insert_id = $db->lastInsertId(); ?>
Vous avez la possibilité d'utiliser la méthode update()
pour créer une instruction UPDATE et lier vos données pour la mise à jour.
(Les données liées sont automatiquement protégées pour prévenir tout risque d'injection SQL).
Vous pouvez fournir une clause WHERE facultative pour spécifier quelle ligne mettre à jour. (Notez que la clause WHERE n'est pas un paramètre échappé, vous devez donc protéger vous-même sa valeur).
<?php // // UPDATE round_table // SET favorite_color = "yellow" // WHERE first_name = "Robin"; // // crée un objet $db, en ensuite... // les nouvelles valeurs à mettre à jour, en utilisant la syntaxe nom_colonne => valeur_colonne $set = array ( 'favorite_color' => 'yellow', ); // la table à mettre à jour $table = 'round_table'; // la clause WHERE $where = $db->quoteInto('first_name = ?', 'Robin'); // mise à jour de la table, et récupération du nombre de lignes affectées $rows_affected = $db->update($table, $set, $where); ?>
Vous avez la possibilité d'utiliser la méthode delete()
pour créer une instruction DELETE.
Vous pouvez fournir optionellement une clause WHERE.
(Notez que la clause WHERE n'est pas un paramètre échappé, vous devez donc protéger vous-même sa valeur).
<?php // // DELETE FROM round_table // WHERE first_name = "Patsy"; // // crée un objet $db, en ensuite... // la table dont on veut supprimer des données $table = 'round_table'; // la clause WHERE $where = $db->quoteInto('first_name = ?', 'Patsy'); // mise à jour de la table, et récupération du nombre de lignes affectées $rows_affected = $db->delete($table, $where); ?>
Bien que vous puissiez interroger la base de données directement avec la méthode query()
tout ce que vous avez besoin
de faire et des sélectionner des lignes et obtenir le résultat. La série de méthodes fetch*()
vous permet de le faire.
Pour chaque méthode fetch*()
, vous passez une instruction SQL; si vous utilisez des marqueurs de remplacement dans cette
instruction, vous devrez aussi passer un tableau contenant la valeur à échapper, pour qu'elle soient protégées et remplacées dans la requête.
Les méthodes fetch*()
sont :
fetchAll()
fetchAssoc()
fetchCol()
fetchOne()
fetchPairs()
fetchRow()
<?php // crée un objet $db, en ensuite... // ?? retrouve les colonnes de chaque ligne comme un tableau séquentiel ?? $result = $db->fetchAll( "SELECT * FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // ?? retrouve les colonnes de chaque ligne comme un tableau associatif ?? // la première colonne est utilisée comme la clé du tableau $result = $db->fetchAssoc( "SELECT * FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // retrouve la première colonne de résultat $result = $db->fetchCol( "SELECT first_name FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // retrouve uniquement la première valeur $result = $db->fetchOne( "SELECT COUNT(*) FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // retrouve la série de paries clé/valeurs; la première colonne et le tableau de clé // la seconde le tableau de valeurs $result = $db->fetchPairs( "SELECT first_name, favorite_color FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // retrouve uniquement la première ligne retournée $result = $db->fetchRow( "SELECT * FROM round_table WHERE first_name = :name", array('name' => 'Lancelot') ); ?>