3.4. Zend_Db_Table

3.4.1. Introduction

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.

3.4.2. Mise en Route

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();
?>
        

3.4.3. Nom de la table et clé primaire

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();
    }
}
?>
        

3.4.4. Insertion de lignes

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);
?>
        

3.4.5. Mise à jour de lignes

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);
?>
        

3.4.6. Suppression de lignes

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);
?>
        

3.4.7. Trouver des lignes par clé primaire

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));
?>
        

3.4.8. Aller chercher une ligne

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);
?>
        

3.4.9. Aller chercher plusieurs lignes

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);
?>
        

3.4.10. Ajouter votre propre logique

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);
    }
}
?>