Una delle feature del framework Ruby On Rails più potenti è l’implementazione del pattern ActiveRecord. Esso permette di “vedere” ogni record di una tabella del database come istanze di una classe permettendo di eseguire le normali operazioni di CRUD (Create, Read, Update, Delete) con poche righe di codice.
L’implementazione di ActiveRecord in Rails è molto complessa, permette di effettuare validazioni e avere riferimenti a chiavi esterne. Vediamo un’implementazione più semplice in PHP, ma comunque efficace.
Cercheremo di arrivare ad un’implementazione molto potente in qualche puntata.
Il concetto che sta alla base di active record è di trasformare l’accesso al database in accesso a una classe.
Cominciamo a definire una classe base che abbia l’accesso al database. Per semplificare utilizzeremo la classe PEAR::MDB2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | require 'MDB2.php'; abstract class ActiveRecordBase { protected $__db; // Dichiariamo un oggetto "protected" per l'accesso al DB protected $__primary_key = "id"; // Definiamo una chiave primaria per la tabella. Può essere poi // modificata per ogni singola classe che estende questa. protected $__fields; // In questo attributo di tipo array andremo a salvare i campi della nostra tabella (escluso il campo primary key) protected $__table; // In questo attributo salviamo il nome della tabella /** * Il costruttore istanzia una connessione con il db e se sono presenti dei dati * li salva nell'oggetto (non nel database!) */ public function __construct($data=array()){ $this->db = &MDB2::connect(DB_DSN); // DB_DSN è una stringa che contiene di dati accesso al DB $this->__table = strtolower(get_class($this)); if (!empty($data)) foreach ($data as $key => $value){ $this->$key = $value; $this->fields[] = $key;} } /** * Definiamo un metodo per create un nuovo Record. * Esso è privato perché verrà utilizzato dal metodo save() */ private function create(){ // Creaimo l'istruzione SQL a partire dai campi disponibili $sql = "INSERT INTO ".$this->__db->quoteIdentifier($this->table)." ("; $first = true; $data = array(); foreach ($this->__fields as $field){ if (!$first) $sql.=","; $sql.= $this->__db->quoteIdentifier($field); $data[] = $this->$field; $first = false; } $sql.= ") VALUES ("; for ($i = 0; $i < count($fields); $i++) if ($i=0) $sql.="?" else $sql.=",?"; $sql:=");"; $prep = $this->__db->prepare($sql); $res = $prep->execute($data); $pkey_field = $this->__primary_key; if ($res) $this->$pkey_field = $this->__db->lastInsertID($this->__table); return $res; } private function update(){ $sql = "UPDATE ".$this->__db->quoteIdentifier($this->__table)." SET "; $first = true; $data = array(); foreach ($this->__fields as $field){ if (!$first) $sql.=","; $sql = "$field = ?"; $data[] = $this->$field; $first = false; } $pkey_field = $this->__primary_key; $sql = "WHERE ".$this->db->quoteIdentifier($pkey_field)." = ".$this->db->quote($this->$pkey_field); $prep = $this->__db->prepare($sql); return $prep->execute($data); } private function delete(){ $pkey_field = $this->__primary_key; $sql = "DELETE FROM ".$this->__db->quoteIdentifier($this->__table). " WHERE ".$this->db->quoteIdentifier($pkey_field)." = ".$this->db->quote($this->$pkey_field); return $this->__db->query($sql); } public function save(){ $pkey_field = $this->__primary_key; if (!isset($this->$pkey_field)) return $this->create(); else return $this->update(); } public function destroy(){ $pkey_field = $this->__primary_key; if (isset($this->$pkey_field)) return $this->delete(); else return false; } } |
In questa implementazione, ancora in stato “embrionale”, è possibile creare un nuovo record.
Un uso molto semplice potrebbe essere creare una classe che estenda la base e istanziarne un oggetto:
1 2 3 4 | require 'ActiveRecordBase.class.php' class Dog extends ActiveRecordBase {} $dog = new Dog(array('name' => 'Pluto', 'age' => '7')); $dog->save(); |
Il precedente script inserisce un nuovo record in una tabella ‘dog’ (stessa nome della classe che estende ActiveRecordBase) assegnando gli attributi ‘name’ e ‘age’.
La primary key viene implicitamente impostata come “id” (ovviamente se il campo ha l’attributo auto_increment) e il valore inserito automaticamente.
Il tutto in 3 righe di codice, molto molto semplici…non è una bella comodità?
Più avanti vedremo come effettuare ricerche, e quindi come implementare il metodo “find” e migliorare ulteriormente la classe base in modo da gestire meglio errori, validazioni e chiavi esterne.


















0 Comments
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment