Model

Zend Framework non fornisce una classe Zend_Model, dato che il model è la nostra logica di business ed è lasciata a noi la decisione di come farla funzionare. Ci sono molti componenti che possimamo usare, dipende dalle necessità. Un approccio consiste nell’avere una classe model per ciascuna entità della nostra applicazione e poi usere degli oggetti “mapper” per caricare e salvare le varie entità nel database. Questo approccio è documentato nella guida QuickStart a Zend Framework: http://framework.zend.com/manual/en/learning.quickstart.create-model.html.

Per questo tutorial, andremo a creare un model che estende Zend_Db_Table e usa Zend_Db_Table_Row. Zend Framework fornisce Zend_Db_Table che implementa il pattern Table Data Gateway che permette di interfacciarsi ai dati di una tabella del database. Dobbiamo essere consapevoli che il pattern Table Data Gateway può essere limitativo in un sistema più ampio. Potremmo avere anche la tentazione di mettere il codice di accesso al database in una action di un controller poiché questo viene esposto da Zend_Db_Table.

Zend_Db_Table_Abstract è una classe astratta, dalla quale deriveremo la nostra classe specifica per gestire gli album. Non ha importanza come chiameremo la nostra classe, ma ha senso chiamarla con lo stesso nome della tabella del database.

Il nostro progetto dispone di un autoloader di default istanziato da Zend_Application che mappa le classi di risorsa appartenenti ad un modulo nella directory dove esso è definito. Per la cartella principale application/ useremo il prefisso Application_.

L’autoloader associa le risorse e le relative directory in questo modo:

PrefissoDirectory
Formforms
Modelmodels
Model_DbTablemodels/DbTable
Model_Mappermodels/mappers
Pluginplugins
Serviceservices
View_Filterviews/filters
View_Helperviews/helper

Poiché chiameremo il model con lo stesso nome della tabella del database “albums” ed useremo Zend_Db_Table, la nostra classe si chiamerà Application_Model_DbTable_Albums, che verrà salvata in applications/models/DbTable/Albums.php.

Per indicare a Zend_Db_Table il nome della tabella che useremo, dobbiamo impostare un attributo protetto $_name con il nome della tabella. Inoltre Zend_Db_Table assumerà che la nostra tabella possieda una chiave primaria di nome “id” di tipo auto-increment. Anche il nome di questa colonna può essere cambiato se necessario.

Possiamo usare il comando zf per farci fare parte del lavoro, quindi lanciamo il seguente comando da terminale:


zf create db-table Albums albums

Lo strumento a riga di comando ha creato adesso il file Albums.php nella cartella application/models/DbTable. All’interno di questo file c’è la classe Application_Model_DbTable_Albums nella quale è impostato il nome della tabella del database con cui comunicherà.

Adesso dobbiamo aggiungere qualche funzionalità, modifichiamo quindi application/models/DbTable/Albums.php e aggiungiamo i metodi getAlbum(), addAlbum(), updateAlbum() e deleteAlbum() e ora dovrebbe assomigliare a qualcosa di simile a questo:

zf-tutorial/application/models/DbTable/Albums.php

<?php
class Application_Model_DbTable_Albums extends Zend_Db_Table_Abstract
{
   protected $_name = 'albums';

   public function getAlbum($id)
   {
   $id = (int)$id;
   $row = $this->fetchRow('id = ' . $id);
   if (!$row) {
       throw new Exception("Could not find row $id");
   }
   return $row->toArray();
   }

   public function addAlbum($artist, $title)
   {
   $data = array(
       'artist' => $artist,
       'title' => $title,
   );
   $this->insert($data);
   }

   public function updateAlbum($id, $artist, $title)
   {
   $data = array(
       'artist' => $artist,
       'title' => $title,
   );
   $this->update($data, 'id = '. (int)$id);
   }

   public function deleteAlbum($id)
   {
   $this->delete('id =' . (int)$id);
   }
}

Abbiamo creato quattro metodi helper che la nostra applicazione userà per interfacciarsi alla tabella del database. getAlbum() recupera una singola riga sotto forma di array, addAlbum() crea una nuova riga nel database, updateAlbum() aggiorna la riga di un album e deleteAlbum() rimuove completamente una riga. Il codice di ogni metodo è auto esplicativo. Sebbene non necessario ai fini di questo tutorial, è anche possibile indicare a Zend_Db_Table le tabelle correlate in modo che possa trovare anche dati relazionati. Ora abbiamo bisogno di riempire il controller dei dati provenienti dal model affinché gli script di view li possano mostrare, ma prima di procedere dobbiamo capire come funziona il sistema di view di Zend Framework.