Newsgroup: it.comp.www.php
Titolo: Domanda veloce sul php templating con OOP e include()

header ci mette 1, come da manuale)
Ho provato con file_gets_contents ma nada, non voglio nemmeno pensare
di usare eval, l'unica soluzione che mi viene in mente è di usare il
buffer con le funzioni ob_* ma mi sembra un pò overkill.

 buffer con le funzioni ob_* ma mi sembra un p� overkill.
Se proprio vuoi seguire questa strada ricorda di fare tutti i controlli
del caso sugli include...
Inoltre ricorda che per migliorare le performance un meccanismo di cache
lo devi prevedere...
Comunque qualcosa del genere di quello voluto potrebbe essere:
----------------------------------
-- class/t1.class.php           --
----------------------------------
<?php
class t1
{
  private $header;
  private $additionalHeader;
  private $assign;
  private $baseTemplate;
  private $footer;
  private $body;
  function __construct($baseTemplate,$header,$footer)
  {
    $this->header = $header;
    $this->baseTemplate = $baseTemplate;
    $this->footer = $footer;
    $this->additionalHeader = array();
    $this->assign = array();
    $this->body = "";
  }
  public function addMoreHeader($arrayOfMoreHeader)
  {
    foreach($arrayOfMoreHeader as $head)
    {
      $this->additionalHeader[] = $head;
    }
  }
  public function addAssignement($assign)
  {
    foreach($assign as $hash => $text)
    {
      $this->assign[$hash] = $text;
    }
  }
  private function read($file)
  {
    $file = "inc/" . $file;
    if(file_exists($file))
    {
      $this->body .= file_get_contents($file);
    }
  }
  public function render()
  {
    $this->read($this->header);
    if(sizeof($this->addittionalHeader))
    {
      foreach($this->addittionalHeader as $head)
      $this->read($head);
    }
    $this->read($this->baseTemplate);
    $this->read($this->footer);
    foreach($this->assign as $hash => $text)
    {
      $this->body = str_replace($hash,$text,$this->body);
    }
    return $this->body;
  }
}
?>
----------------------------------
-- base.php                     --
----------------------------------
<?php
require_once("class/t1.class.php");
$pagina = new t1("base.html","basehead.html","basefoot.html");
$pagina->addAssignement(array(
  "%TITOLO%" => "pagina di test",
  "%CONTENUTO%" => "bla bla bla bla <br/>bla..."
));
echo $pagina->render();
?>
----------------------------------
-- inc/base.html                --
----------------------------------
  <body>
    <div id="contenuto">
      %CONTENUTO%
    <div>
  </body>
----------------------------------
-- inc/basehead.php             --
----------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"
http://www.w3.org/TR/html4/strict.dtd
"
<html>
  <head>
    <title>%TITOLO%</title>
  </head>
----------------------------------
-- inc/basefoot.php             --
----------------------------------
<div id="footer">bla bla bla</div>
</html>
--------------------------------


naa, file_get_contents e via di replace è un massacro a livello di
prestazioni.. nei template voglio averci la stampa delle variabili,
cioè echo $this->variabile';
Per quel che riguarda la sicurezza sarò l'unico a creare e modificare
i template, quindi non ci sono problemi in questo senso.
Forse mi sono spiegato male, il metodo include funziona alla grande,
solo volevo sapere se c'è un modo intelligente per, eventualmente,
caricare il contenuto renderizzato del template in una variabile.
Ad esempio, drupal fà una cosa simile con i nodi, tutti i vari
template e pezzi che compongono un nodo te li ritrovi nella variabile
$node->content... da li puoi stamparlo a video o manipolarlo come ti
pare.
Come ho già detto, l'unico sistema che mi viene in mente sono le
funzioni ob_* passandogli una funzione di callback, volendo, ma non mi
sembra il metodo più brillante.

 sembra il metodo più brillante.
Perche` non ti sembra brillante? E` il metodo piu` pulito. Ti basta far 
partire l'ob prima dell'include, e fermarlo subito dopo, catturando il 
buffer in una variabile.
Sono due comandi in tutto. Pulito, veloce, efficiente. :)
Bye.

 sembra il metodo pi� brillante.
beh comunque se vai a vedere i test svolti qua:
http://www.raditha.com/wiki/Readfile_vs_include
alla fine vedi che in realt� file_get_content ha performance abbastanza
decenti che puoi comunque aumentare realizzando un meccanismo di cache.
header fa un inclusione e una eval alla fine..
"include()
The include() statement includes and evaluates the specified file."
e le performance sono meno buone di quanto credi.
comunque se vuoi una cosa del genere puoi usare ob_* anche senza callback:
<?php
  ob_start();
  include "inc/basehead.html";
  $head = ob_get_contents();
  include "inc/base.html";
  $page = ob_get_contents();
  ob_end_clean();
  var_dump($head, $page);
?>
l'ob_get_contents ti da il progressivo con il clean non invii nulla...

 comunque se vuoi una cosa del genere puoi usare ob_* anche senza callback
si, era solo per dire, il callback è comodo se devi fare ulteriori
elaborazioni alla stringa.
@pellizzari: scusa per il quote lungo, per quel che riguarda le
funzioni ob_*.. in effetti non sono la fine del mondo, non sò, è che
quando ho abbozzato un codice con ob_* mi è sembrato di affogare in un
bicchiere d'acqua quando la soluzione era una cosa molto più semplice
ed efficace (non che le funzioni ob_* siano difficili da usare)

    
Anche io ti consiglierei le funzioni ob_* se non vuoi toccare
minimamente bar.php, in cui immagino ci sia codice html
frammisto a qualcosa tipo <?php echo $this->qualcosa; ?>
se invece hai voglia di maneggiarlo un'altra soluzione
potrebbe essere avere dentro bar.php del codice tipo
<?php
$html= <<<EOD
<div>$this->qualcosa</div>
EOD;
?>
includendo bar.php ti ritrovi in $html il codice valutato
senza impazzire con apici, doppi apici e cosucce del genere
p.s. inizia a non funzionare invece, se in bar.php hai anche
pezzi di codice php con if for e altre cosucce :)
ciao

 ciao
Cosa che invece ho.. oddio, nei file di template la logica è minima:
appunto qualche ciclo e controlli if (su variabili booleane).
Bhè, ora stò provando ob_* e in effetti non lavora male:
ob_start();
include('pippo.tpl.php');
$pippo = ob_get_clean();
e voilà..
solo che bho, sarò paranoico io, ma ho la sensazione di usare un
martello per avvitare una vite..
farò un sacco di profiling ;)

    
Se poi posti i risultati del profiling... :)
ho comuque sempre dei dubbi, sull'avere delle stringone di qualche Kbyte
che si sommano magari ad array stratosferici.. tirati gi� da db
insomma bisogna stare anche un po attenti all'occupazione della ram
[bisogna comunque impegnarsi per arrivare a saturare i MByte :)]


Hai perfettamente ragione, infatti l'esempio di drupal secondo me è un
pò un'esagerazione (non sò selo hai mai usato e se ti sei tolto lo
sfizio, dentro un template, di fare un var_dump($node)... c'è la
bibbia e i primi due capitoli della divina commedia li dentro)
Il mio è per ora un'esigenza marginale, solitamente stampo
direttamente con include al momento di renderizzare il tutto nel view,
ma mi è capitato di aver in certi casi dover processare ulteriormente
l'output..