EndEffekt: selbst gebastelte Template-Engines

Beitrag lesen

(Hallo|Hi(ho)|Tag) EndEffekt,

Frohe Weihnachten,
ich hoffe hier ist trotzdem der ein oder andere hilfbereite Mensch anzutreffen.

Ich hab das alljährliche Familien-Ritual schon hinter mir ...

Mein Problem sieht folgendermaßen aus:
Ich bastel mir grade etwas ähnliches, wie eine Template-Engine zusammen, dafür muss ich in einem String (, der HTML-Code enthält) nach so einem Gebilde suchen:

{variabler_variablenname}

und selbigen Ausdruck durch eine globale Variable, die diesen Namen trägt, ersetzen; in diesem Beispiel also durch:

$GLOBALS["variabler_variablenname"]

Hab ich mir gedacht, machse dat mir preg_replace()!
Klug wie ich bin, bastel ich mir also den Funktionsaufruf mit entsprechenden Parametern zusammen, der wie folgt aussieht:

$code = preg_replace("/{(.+)}/", $GLOBALS["$1"], $code);

War nicht so klug ... ;-)
Wenn du den Inhalt der globalen Variable als Ersetzen-Parameter benötigst, musst du den auch entsprechend einbauen:

$neu = preg_replace('/{(.+)}/e', '$GLOBALS["$1"]', $alt);


>   
> Der PCRE-Modifikator '/e' sorgt dafür, dass der im Ersetzen-Parameter stehende String als PHP-Code ausgeführt wird (Besser als diese Methode ist hier aber oftmals der Aufruf von preg\_replace\_callback()).  
>   
> Allerdings baust du dir durch diese Vorgehensweise eine Menge Stolperstellen in dein Script ein.  
>   
> Was ist, wenn der in deinem Template auftauchende Bezeichner nicht im $GLOBALS-Array vorhanden ist? Diesen Fehler müsstest du abfangen. Und was ist, wenn irgendwer in dein Template "{fuer\_dein\_Script\_ganz\_wichtige\_variable}" schreibt?  
>   
> > (PS: Das Ganze geschieht in einer Funktion, daher muss ich mit $GLOBALS arbeiten)  
> Hüh? Funktionen in PHP dürfen Parameter übergeben bekommen. Das tut denen gar nicht weh. Vielleicht solltest du dir lieber sowas bauen:  
>   
> ~~~php
  

> function flat_template_bastelei(  
>   $template_src,    // die Template-Datei (die mit den "{...}")  
>   $template_array   // das Array, das die Ersetzungen beinhaltet  
> ) {  
>   // wir definieren uns eine statische Variable  
>   // deren Inhalt merkt sich die Funktion,  
>   // sie bleibt also bei jedem Funktionsaufruf gleich  
>   static $callback;  
>   
>   if ( empty($callback) ) {  
>     // beim ersten Aufruf weisen wir der statischen Variablen  
>     // eine so genannte "anonyme" oder "Lambda-Style"-Funktion  
>     // zu  
>     $callback = create_function(  
>       '$matches // ein Array, das alle Treffer beinhaltet',  
>       '  
>         // $1 findet sich in $matches[1] ...  
>   
>         // gibts die Template-Variable überhaupt?  
>         if ( !isset( $template_array[ $matches[1] ] ) ) {  
>           return $matches[1];  
>         }  
>         return $template_array[ $matches[1] ]  
>       '  
>     );  
>   }  
>   
>   return preg_replace_callback(  
>     '/\{(.+)\}/',  // dein regulaerer Ausdruck  
>     $callback,     // die anonyme Funktion, die aufgerufen wird, wenn  
>                    // dein regulaerer Ausdruck "passt"  
>     $template_src  
>   );  
> }  
> 

Guckst du dazu auch ins PHP-Handbuch:

Statische Variablen in Funktionen
create_function()
preg_replace_callback()

MffG
EisFuX

Auch dir vielen Dank.
Einige sehr nützliche Ratschläge, über die ich mir auch schon zumindestteilweise Gedanken gemacht habe.

Das Ding soll ja keine vollwertige Template-Engine werden, sondern lediglich auf eine ganz simple Art und Weise HTML von PHP trennen (ich weiß nix anderes macht eine Template-Engine, aber ich will halt was schlichtes - ich erwarte nicht, dass das jetzt irgendwer versteht)

Nadann mit preg_replace_callback klappts prima!

Frohe Weihnachten nochmal.