EisFuX: 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:

  
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