martedì 25 novembre 2008

Separazione delle carriere in php

php è considerato un linguaggio "semplice" per lo sviluppo web, spesso contrapposto alle piattaforme "serie" come .NET e Java: questo è dovuto soprattutto all'uso semplice che la maggior parte degli sviluppatori ne fanno.
Ma anche in php si possono usare paradigmi di progettazione più evoluti del semplice incapsulamento nel codice html; ad esempio, si possono usare i template, per separare lo strato di visualizzazione da quello di elaborazione.
Il template è un file prototipo che non contiene (quasi) codice php e che può essere quindi gestito anche da chi non conosce il php: può essere un file html, xml, javascript o di qualunque altro tipo si voglia. La sua particolarità è quella di poter contenere eventuali segnaposto utilizzabili da php.
Il codice php può compilare il template con diverse tecniche (io ne mostrerò solo una, basata sulla funzione eval) e restituire il documento opportunamente modificato.
Ad esempio, si possono avere i tre file:
  • mondorux.php: la pagina che sarà richiesta dal browser e che controlla il processo;
  • component.php: contiene la classe Component, che incapsula il meccanismo di rendering dei contenuti;
  • template.html: il prototipo che "vestirà" mondorux.php.
Ecco il codice, che mi appresto a commentare.

template.html

<html>
    <head>
        <title>$titolo</title>
    </head>
    <body>
        <h1>$titolo</h1>
        <p>$saluto</p>
    </body>
</html>
Come si può vedere, in questa pagina html non c'è codice php, a parte quelle strane stringhe precedute da '$': esse sono solo dei segnaposto (nota: questo non è l'unico modo per scrivere il template).

component.php

<?php
class Component{
    var $_template;
    var $_parameters_array;

    /* costruttore, imposta il template */
    function Component($template){
        $this->_template = str_replace("\"","\\\"",implode("",file($template)));
    }

    /* legge un array associativo di nomi di variabili e loro valori */
    function setParameters($parameters_array){
        $this->_parameters_array = $parameters_array;
    }

    /* esegue la resa del template */
    function render(){
        if(is_array($this->_parameters_array)){
            foreach($this->_parameters_array as $v_name => $v_value){
                eval("$v_name = \$v_value;");
            }
        }
        eval("\$compiled = \"".$this->_template."\";");
        return $compiled;
    }
}
?>
Questa classe (perdonate lo stile PHP4, un po' obsoleto) incapsula il template e il meccanismo di rendering, che ruota tutto intorno alla funzione eval (nel metodo render), che valuta come codice php la stringa passata come parametro.
Il metodo getParameters raccoglie un array associativo di coppie (nome, valore) in modo che il codice cliente possa impostare i contenuti della pagina.

mondorux.php

<?php
require("component.php");
$pagina = new Component("template.html");
$pagina->setParameters(
    array(
        '$titolo' -> "Template php",
        '$saluto' -> "Ciao mondo, ma che belli i template!"
    )
);
$pagina->render();
?>

Come si può vedere, in questo codice non c'è traccia di come sarà reso il documento (in questo caso: html).
mondorux.php usa la classe Component, chiedendole di eseguire, tramite il template "template.html", la resa dei contenuti, ossia i parametri $titolo e $saluto i cui valori sono assegnati nell'array.
Con questa tecnica abbiamo ottenuto una quasi completa separazione del codice di elaborazione (mondorux.php) dal codice di visualizzazione (template.html), implementando così il famoso (e utile) pattern Model-View-Controller.

Nessun commento: