Le composant Zend_Db_Table
constitue le module de gestion des tables du Framework Zend.
Il se connecte à votre base de données via Zend_Db_Adapter
, examine le schéma d'une table puis vous aide à manipuler
et aller chercher les lignes de cette table.
La première chose à faire consiste à fournir à la classe abstraite Zend_Db_Table
un adaptateur de base de données par défaut;
sauf mention contraire de votre part, toutes les instances de Zend_Db_Table
utiliseront cet adaptateur par défaut.
<?php // on définit un adaptateur require_once 'Zend/Db.php'; $parametres = array ( 'adapter' => 'PDO_MYSQL', 'host' => '127.0.0.1', 'username' => 'arthur', 'password' => '******', 'dbname' => 'camelot' ); $db = Zend_Db::factory($parametres); // on définit l'adaptateur par défaut de tous les objets Zend_Db_Table require_once 'Zend/Db/Table.php'; Zend_Db_Table::setDefaultAdapter($db); ?>
Ensuite, supposons que vous disposez d'une table appelée "table_ronde" dans votre base de données.
Pour utiliser Zend_Db_Table
sur cette table de base de données, étendez simplement Zend_Db_Table
pour créer
une nouvelle classe appelée TableRonde (notez que nous avons transformé le nom table_ronde en utilisant la notation Camel).
Vous pourrez ensuite examiner via cette classe la table 'table_ronde', manipuler ses lignes et aller chercher des lignes particulières.
<?php class RoundTable extends Zend_Db_Table {} $table = new RoundTable(); ?>
Par défaut, Zend_Db_Table
s'attend à ce que le nom de la table de votre base de données soit le même que son propre
nom de classe (en le convertissant d'abord de la NotationCamel vers la notation mots_separes_par_tirets_bas). Ainsi,
une classe Zend_Db_Table
appelée UnNomDeTable est associée à une table SQL appelée 'un_nom_de_table'. Si vous voulez que
votre classe soit associée à un nom autre que la forme avec tirets bas du nom de la classe, surchargez la propriété $_name
lorsque vous définissez votre classe.
<?php class NomDeLaClasse extends Zend_Db_Table { // le nom par défaut pour la table est 'nom_de_la_classe' // mais nous voulons utiliser un autre nom protected $_name = 'un_autre_nom_de_table'; } ?>
Par défaut, Zend_Db_Table
s'attend à ce que votre table possède une clé primaire
nommée 'id'. (C'est mieux si cette colonne est auto-incrémentée, mais ce n'est pas une nécessité.)
Si votre clé primaire se nomme autrement que 'id', vous pouvez surcharger la propriété $_primary
lorsque vous définissez votre classe.
<?php class NomDeLaClasse extends Zend_Db_Table { // la clé primaire par défaut est 'id' // mais nous voulons utiliser un autre nom protected $_primary = 'un_autre_nom_de_colonne'; } ?>
Vous pouvez aussi définir ces propriétés dans la méthode _setup()
de votre classe; assurez-vous simplement
d'appeler la méthode _setup()
de la classe-parente une fois que c'est fait.
<?php class NomDeLaClasse extends Zend_Db_Table { protected function _setup() { $this->_name = 'un_autre_nom_de_table'; $this->_primary = 'un_autre_nom_de_colonne'; parent::_setup(); } } ?>
Pour insérer une nouvelle ligne dans votre table, appelez simplement insert()
en lui passant un tableau associatif
de données sous la forme colonne:valeur. Les données seront échappées automatiquement pour vous et l'ID de la dernière
insertion sera renvoyé.
(Notez qu'en cela cette méthode diffère de Zend_Db_Adapter::insert()
, qui renvoie le nombre de lignes affectées.)
<?php // // INSERT INTO table_ronde // (titre, prenom, couleur_preferee) // VALUES ("Roi", "Arthur", "bleu") // class TableRonde extends Zend_Db_Table {} $table = new TableRonde(); $donnees = array( 'titre' => 'Roi', 'prenom' => 'Arthur', 'couleur_preferee' => 'bleu', ) $id = $table->insert($donnees); ?>
Pour mettre à jour des lignes de votre table, appelez update()
en lui passant un tableau associatif des données à
modifier sous la forme colonne:valeur
ainsi qu'une clause WHERE permettant de déterminer quelles lignes doivent
être mises à jour. Cette méthode mettra à jour la table et renverra le nombre de lignes affectées.
Les données à modifier seront automatiquement échappées pour vous mais pas la clause WHERE, que vous devez échapper vous-même
à l'aide de l'objet Zend_Db_Adapter
de la table.
<?php // // UPDATE table_ronde // SET couleur_preferee = "jaune" // WHERE prenom = "Robin" // class TableRonde extends Zend_Db_Table {} $table = new TableRonde(); $db = $table->getAdapter(); $set = array( 'couleur_preferee' => 'jaune', ) $where = $db->quoteInto('prenom = ?', 'Robin'); $lignes_affectees = $table->update($set, $where); ?>
Pour supprimer des lignes de votre table, appelez delete()
en lui passant une clause WHERE permettant
de déterminer quelles lignes doivent être supprimées. Cette méthode renverra ensuite le nombre de lignes supprimées.
La clause WHERE ne sera pas échappée pour vous et vous devez donc l'échapper vous-même à l'aide de l'objet Zend_Db_Adapter
de la table.
<?php // // DELETE FROM table_ronde // WHERE prenom = "Patrick" // class TableRonde extends Zend_Db_Table {} $table = new TableRonde(); $db = $table->getAdapter(); $where = $db->quoteInto('prenom = ?', 'Patrick'); $lignes_affectees = $table->delete($where); ?>
Si vous le souhaitez, vous pouvez facilement obtenir des lignes de la table en fonction des valeurs de leurs clés primaires, grâce
à la méthode find()
. Cette méthode renvoie un objet Zend_Db_Table_Row
si vous tentez de retrouver une seule clé ou un objet
Zend_Db_Table_Rowset
si vous tentez de retrouver plusieurs clés.
<?php class TableRonde extends Zend_Db_Table {} $table = new TableRonde(); // SELECT * FROM table_ronde WHERE id = "1" $ligne = $table->find(1); // SELECT * FROM table_ronde WHERE id IN("1", "2", 3") $lignes = $table->find(array(1, 2, 3)); ?>
Même si vous pouvez facilement retrouver une ligne par sa clé primaire, vous aurez souvent besoin d'ajouter
différentes conditions à la requête lorsque vous cherchez à obtenir une ligne particulière. Zend_Db_Table
offre précisément dans ce but la méthode fetchRow()
. Appelez fetchRow()
en lui passant une clause WHERE
(et une clause ORDER optionnelle) et Zend_Db_Table
renverra un objet Zend_Db_Table_Row
associé au premier
enregistrement qui correspond aux conditions spécifiées.
Notez que la clause WHERE ne sera pas échappée pour vous et vous devez donc l'échapper vous-même à l'aide de l'objet Zend_Db_Adapter
de la table.
<?php // // SELECT * FROM table_ronde // WHERE titre = "Sire" // AND prenom = "Robin" // ORDER BY couleur_preferee // class TableRonde extends Zend_Db_Table {} $table = new TableRonde(); $db = $table->getAdapter(); $where = $db->quoteInto('titre = ?', 'Sire') . $db->quoteInto('AND prenom = ?', 'Robin'); $order = 'couleur_preferee'; $ligne = $table->fetchRow($where, $order); ?>
Si vous avez besoin d'obtenir plusieurs lignes en même temps, utilisez la méthode fetchAll()
.
Comme pour fetchRow()
, elle prend en argument une clause WHERE et une clause ORDER mais aussi un décompte
limite et une valeur offset limite afin de restreindre le nombre de lignes renvoyées. La méthode renverra un objet
Zend_Db_Table_Rowset
contenant les enregistrements sélectionnés.
Notez que la clause WHERE ne sera pas échappée pour vous et vous devez donc l'échapper
vous-même à l'aide de l'objet Zend_Db_Adapter
de la table.
<?php class TableRonde extends Zend_Db_Table {} $table = new TableRonde(); $db = $table->getAdapter(); // SELECT * FROM table_ronde // WHERE titre = "Sire" // ORDER BY prenom // LIMIT 10 OFFSET 20 $where = $db->quoteInto('titre = ?', 'Sire'); $order = 'prenom'; $decompte = 10; $offset = 20; $lignes = $table->fetchAll($where, $order, $decompte, $offset); ?>
En bon module de table, Zend_Db_Table
se prête bien à l'encapsulation de votre propre logique.
Vous pouvez par exemple surcharger les méthodes insert()
et update()
pour qu'elles manipulent ou valident les
données avant que celles-ci n'aillent dans la base de données.
<?php class TableRonde extends Zend_Db_Table { public function insert($donnees) { // on ajoute un timestamp if (empty($donnees['cree_le'])) { $donnees['cree_le'] = time(); } return parent::insert($data); } public function update($donnees) { // on ajoute un timestamp if (empty($donnees['cree_le'])) { $donnees['cree_le'] = time(); } return parent::update($donnees); } } ?>
De même, vous pouvez ajouter vos propres méthodes find()
pour rechercher des enregistrements selon un critère autre que la clé primaire.
<?php class TableRonde extends Zend_Db_Table { public function findAllParNom($nom) { $db = $this->getAdapter(); $where = $db->quoteInto("nom = ?", $nom); $order = "prenom"; return $this->fetchAll($where, $order); } } ?>