WebFrameWorker

gennaio 21, 2007

screzi tra PEAR DataObject e datetime (MySql)

Filed under: DataObject,datetime,Pear,PHP — stablum @ 3:27 pm

Oggi ho potuto sperimentare come il DataObject non abbia in particolare simpatia il tipo datetime mentre tentavo di fare un override del metodo dataobject::insert() per impostare il timestamp di inserimento di un record.

Assumento un dataobject $do con un campo data tipo datetime è un impresa impostare la data al giorno attuale.

Il primo tentativo $do->data = now() ovviamente dava problemi, ma sorprendentemente pure $do->data = date("Y-m-d H:i:s") non inseriva la data nella query generata (visibile con $do->debugLevel(5)).

Dopo le preliminari imprecazioni sono andato a scartabellare la documentazione scoprendo alcune orrende alchimie, tra le quali DB_DataObject_Cast::date(..)

Finalmente sono riuscito a inserire la data con $do->data = DB_DataObject_Cast::date(date("Y-m-d H:i:s")) ma purtroppo le informazioni riguardanti ora, minuti e secondi venivano ignorate. La documentazione non dice nulla in proposito a “datetime”.

Come al solito la documentazione migliore è leggere i sorgenti (pear/DB/DataObject/Cast.php) dai quali ho scoperto la funzione non documentata DB_DataObject_Cast::dateTime(..) che, tralaltro, se non gli si passa nessun parametro utilizza la data e il time corrente:

$do->data = DB_DataObject_Cast::dateTime();

Tutta questa complessità a che pro? Non era meglio incapsulare questi “dettagli” all’interno del dataobject invece che pasticciare con funzioni esterne? Cioè: il dataobject ha tutte le informazioni per capire che il campo “data” è un “datetime” e, nel caso gli sia passato un array, avrebbe potuto benissimo fare internamente la conversione nella stringa “Y-m-d H:i:s” per la query.

gennaio 5, 2007

Seagull: un maturo framework MVC

Filed under: PHP,seagull — stablum @ 3:23 pm

E’ già da un paio di mesi che mi sono interessato a seagull.
Si tratta di un framework basato sul pattern Model View Controller e permette di gestire in modo molto elegante concetti come: fitrare le richieste, costruzione dei dati di input sulla richiesta, passaggio dei dati di input alla “azione” del “manager” richiesto e quindi costruzione dei dati di output che vengono passati a un template.

Ecco un esempio di una classe “manager”:

class HelloWorldMgr extends SGL_Manager
{
  function validate($req, &$input){
    $this->validated = true;
    $input->action   = ($req->get('action')) ? $req->get('action') : 'sayGoodBye';
  }
  function HelloWorldMgr(){
    parent::SGL_Manager();
    $this->_aActionsMapping =  array(
      'sayGoodBye'   => array('sayGoodBye'),
      'sayHello'   => array('sayHello'),
    );
  }
  function display(&$output) {
    $this->masterTemplate = 'helloWorld.html';
    $this->pageTitle = "whoa";
    $output->fooz="include_path:".ini_get("include_path");
  }
  function _cmd_sayHello(&$input, &$output) {
    $output->word = 'Hello';
  }
  function _cmd_sayGoodBye(&$input, &$output) {
    $output->word = 'Goodbye';
  }
}

In sostanza la richiesta $reqviene mandata al metodo validate() che costruisce array $input.
Successivamente il framework analizza l’array $this->_aActionsMapping per capire quali metodi (con prefisso _cmd_) sono mappati all’azione richiesta.

Successivamente vengono eseguiti tutti i metodi mappati dando come argomenti l’array di input e quello di output (per riferimento, dato che i dati devono essere modificati).

L’array associativo di output contiene tutte le etichette che verranno macro-espanse nel template (che può essere di tipo flexy, smarty e altri ancora…).

Tale array di output viene passato infine al metodo display (una specie di post-filtro) che si occupa di effettuare le ultime operazioni sui dati che verranno visualizzati, come ad esempio settare il nome del file del template.

Inoltre è disponibile un sistema evoluto di gestione dei permessi, molti moduli gia’ fatti pronti per essere utilizzati e un interfaccia web molto comoda per la configurazione del framework e dei moduli.

Questo sistema di gestire le richieste è una vera e propria manna dal cielo e per le sue caratteristiche lo utilizzerò intensivamente nei mei progetti futuri e seguiranno molti post a proposito ;)

gennaio 4, 2007

PEAR Structures_DataGrid: come mostrare efficacemente dati tabulari

Filed under: datagrid,Pear,PHP — stablum @ 1:22 pm

E’ frequente che un programmatore perda un sacco di tempo nel creare cicli per fare il fetching dei dati e la consecutiva stampa in HTML, magari corredata da un sistema ultra-complicato di paging che da molte frustrazioni. Sembra che una soluzione sia stata trovata grazie a un ottimo sistema di astrazione OO fornitoci da quei geniacci di pear.

DataGrid è un pacchetto PEAR che permette di gestire in modo assolutamente modulare flussi di dati tabulari provenienti dalle più svariate sorgenti (DataBase, CSV, XML…) per mostrarli nei più svariati formati: HTML, XML, MsExcel…

Le sorgenti dati sono rappresentate dai pacchetti PEAR Structures_DataGrid_DataSource_* e i formati di output sono nei pacchetti denominati Structures_DataGrid_Renderer_*

Dopo la creazione dell’oggetto DataGrid si usa il metodo bindDataSource() per “agganciare” la sorgente dei dati (ad esempio un DB_DataObject) e il metodo setRenderer() per impostare il tipo di output.

Molto interessante è l’utilizzo di funzioni callback nel Column Formatter per creare una sorta di post-filtro che va a modificare il dato da visualizzare; ad esempio, in una tabella HTML, invece che mostrare semplicemente un dato, crea un link che conduce al form di modifica di quel dato stesso.

Ecco un esempio che sfrutta la paginazione automatica:
<?php
require 'Structures/DataGrid.php';
// 10 records per page
$datagrid =& new Structures_DataGrid(10);
// Setup your datasource
$options = array('dsn' => 'mysql://user:password@host/db_name');
$test = $datagrid->bind("SELECT * FROM my_table", $options);
if (PEAR::isError($test)) {
echo $test->getMessage();
}
// Print the DataGrid with the default renderer (HTML Table)
$test = $datagrid->render();
if (PEAR::isError($test)) {
echo $test->getMessage();
}
// Print the HTML paging links
$test = $datagrid->render(DATAGRID_RENDER_PAGER);
if (PEAR::isError($test)) {
echo $test->getMessage();
}
?>

per tutto il resto: qui c’è il manuale

gennaio 3, 2007

Propel: un framework ORM per PHP5

Filed under: ORM,PHP,propel — stablum @ 11:48 am

Ieri sera, nell’articolo di wikipedia Object Relationship Modeling ho trovato, tra i collegamenti esterni un ORM per PHP 5 di nome Propel, rilasciato con licenza LGPL.

Propel fa il parsing di file schema scritti in xml per generare Object Model scritti in php, e devo dire che questo mi sembra a naso un anti-pattern

La compatibilità è garantita su un gran numero di database, grazie al layer di astrazione Creole.

Ecco un assaggio di come può essere una parte di uno schema XML:

<table name="book">
<column name="book_id" type="INTEGER" required="true" primaryKey="true"/>
<column name="title" type="VARCHAR" size="100" required="true"/>
<column name="author_id" type="INTEGER" required="true"/>
<foreign-key foreignTable="author">
<reference
local="author_id"
foreign="author_id"/>
</foreign-key>
</table>
<table name="author">
<column name="author_id" type="INTEGER" required="true" primaryKey="true"/>
<column name="fullname" type="VARCHAR" size="40" required="true"/>
</table>

C’è da dire che come schema sembra molto verboso, soprattutto nella specificazione delle foreign key… Mi sembra di capire che l’utilizzo intensivo dell’xml può essere dettato da una necessità inconscia di non voler programmare in quel linguaggio certo non elegantissimo che è il php.

Il sistema di generazione file mi sembra che ricalchi quello di Ruby on Rails e di PRADO, ovvero mediante tool esterni a riga di comando. Non sopporto quest’idea di separare lo sviluppo in due fasi, ovvero “generazione superautomatizza” e “customizzazione” poichè per tornare ad usufruire dei vantaggi della generazione bisogna buttare via le personalizzazioni.

L’utilizzo finale sembra essere piuttosto comodo e comparabile con altri framework simili (si veda il post su doctrine). Inoltre, contrariamente a DB_DataObject, quando vengono inpostati i campi dei record non si usa l’accesso diretto alle variabili d’istanza, ma vengono utilizzati dei setter come si può vedere nel seguente esempio:

$author = new Author();
$author->setFirstName("Leo");
$author->setLastName("Tolstoy");
$pub = new Publisher();
$pub->setName("Viking Press");
$book = new Book();
$book->setTitle("War & Peace");
$book->setIsbn("0140444173");
$book->setPublisher($pub);
$book->setAuthor($author);
// save (insert, in this case) the new object
$book->save();

Di particolare interesse è piuttosto la generazione della sezione WHERE delle SELECT: invece di usare un vero e proprio “pezzo” di codice SQL come fa DB_DataObject con il metodo whereAdd(), propel usa un sistema più avanzato (ed astratto) tramite i cosiddetti Criteria, p.es:

$c = new Criteria();
// Find all authors with first name Karl but
// last name is _not_ Marx.
$c->add(AuthorPeer::FIRST_NAME, "Karl");
$c->add(AuthorPeer::LAST_NAME, "Marx", Criteria::NOT_EQUAL);
// Find all authors with last name of Tolstoy, Dostoevsky, or Bakhtin
$c2 = new Criteria();
$c2->add(AuthorPeer::LAST_NAME, array("Tolstoy", "Dostoevsky", "Bakhtin"), Criteria::IN);

Piuttosto interessante ma eccessivamente verboso per i miei gusti, nonostante fornisca interessanti spunti di riflessione.

L’ultima nota importante è l’emulazione della ON DELETE CASCADE via PHP per tutti i database che non la supportano nativamente, ad esempio MySQL.

Per altre informazioni: qui c’è la guida

Doctrine: l’ORM definitivo?

Filed under: Doctrine,ORM,PHP — stablum @ 11:43 am

Doctrine è un framework di astrazione per le businness class scritto in PHP 5 che permette come tanti altri sistemi, di evitare di scrivere direttamente l’SQL e di usufruire di sistemi di accesso ai dati tramite entità ad oggetti.

Uno dei suoi punti di forza è la facilità di accesso alle entità relazionate, ad esempio:


// NOTE: related record have always the first letter in uppercase
$email = $user->Email;
$email->address = "jackdaniels@drinkmore.info";
$user->save();
// alternative:
$user->Email->address = "jackdaniels@drinkmore.info";
$user->save();

Doctrine inoltre ha un potente linguaggio di query simile all’SQL, ma che viene interpretato dal framework: DQL (Doctrine Query Language).

Devo saperne di più, magari è veramente più potente di DB_DataObject

Theme: Rubric. Blog su WordPress.com.

Follow

Get every new post delivered to your Inbox.