Rieccoci di nuovo a parlare di active record. Nella scorsa puntata avevamo visto una implementazione base del pattern. Essa però è orfana di qualsiasi metodo per la ricerca dei record. Vediamo ora come è possibile farlo.
Rails mette a disposizione diversi metodi per recuperare record dalle tabelle di un database. Il primo è quello di utilizzare il costruttore della classe passando come parametro l’id del record che vogliamo leggere. In molti linguaggi di programmazione Object-Oriented è possibile effettuare l’overload del costruttore, ovvero definire più costruttori per una stessa classe, dove in ogni costruttore cambiano i parametri per numero e/o tipo. In PHP non esiste tale meccanismo (e neanche in Ruby da quanto mi risulta!). Abbiamo visto nella puntata precedente come il costruttore della classe php ActiveRecordBase accetti come unico parametro un array contenente i campi che vogliamo dare ad un nuovo record. Simuliamo ora l’overloading del costruttore in modo che accetti sia l’array che un numero che identifichi l’ID del record.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | abstract class ActiveRecordBase { # qui ci va la dichiarazione degli attributi della classe che tralasciamo # ..... # 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 (!is_array($data) && is_numeric($data)){ $sql = "SELECT * FROM ".$this->__db->quoteIdentifier($this->__table). " WHERE ".$this->__db->quoteIdentifier($this->__primary_key)." = ".$this->__db->quote($data); $data = $this->__db->queryRow($sql); } if (!empty($data)) foreach ($data as $key => $value){ $this->$key = $value; $this->fields[] = $key;} } # Qui prosegue il resto del codice della classe # .... } |
Con questa modifica la nostra classe continua a funzionare accettando 0 o 1 parametro di tipo numerico o array/hash.
Vediamo ora l’implementazione di un metodo find() che permetta di passare come parametro l’ID del record che vogliamo ottenere. Per semplicità d’ora in avanti verranno omesse le dichiarazioni di classe quando non strettamente necessarie.
1 2 3 4 5 6 7 8 9 10 11 | public function find($id){ if (!is_numeric($id)) return false; $sql = "SELECT * FROM ".$this->__db->quoteIdentifier($this->__table)." WHERE ". $this->__db->quoteIdentifier($this->__primary_key)." = ".$this->__db->quote($id); $data = $this->__db->queryRow($data); if (!empty($data)){ foreach ($data as $key => $value){ $this->$key = $value; $this->fields[] = $key;} return true; } return false; } |
Come potete vedere, l’implementazione di find() è molto simile a quella del costruttore. Ricordiamoci il principio DRY (= Don’t Repeat Yourself). Modifichiamo il costruttore e aggiungiamo un metodo privato che assegni a partire da un array i valori corrispondenti agli attributi della classe.
__assignData sarà un metodo privato che assegna i valori agli attributi:
1 2 3 4 5 6 7 | private function __assignData($data=array()){ if (!empty($data)){ foreach ($data as $key => $value){ $this->$key = $value; $this->fields[] = $key;} return true; } return false; } |
Possiamo semplificare il metodo find():
1 2 3 4 5 6 7 | public function find($id){ if (!is_numeric($id)) return false; $sql = "SELECT * FROM ".$this->__db->quoteIdentifier($this->__table)." WHERE ". $this->__db->quoteIdentifier($this->__primary_key)." = ".$this->__db->quote($id); $data = $this->__db->queryRow($data); return $this->__assignData($data); } |
E ora rivediamo il costruttore:
1 2 3 4 5 6 7 8 | 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 (!is_array($data) && is_numeric($data)){ $this->find($data); } $this->__assignData($data); } |


















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