9.4. Zend_Db_Table
Précédent | Chapitre 9. Zend_Db | Suivant

## 9.4. Zend_Db_Table

### 9.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.

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

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

### 9.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);
    ?>

### 9.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);
    ?>

### 9.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);
    ?>

### 9.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));
    ?>

### 9.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);
    ?>

### 9.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);
    ?>

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

Précédent | Niveau supérieur | Suivant
9.3. Zend_Db_Select | Sommaire | 9.5. Zend_Db_Table_Row