ÜbersichtPHP - Templating mit benutzerdefinierten Tags - ist dies eine legitime Verwendung von Eval?
Gegen Ende des Jahres 2009 schrieb ich ein einfaches Template-System für PHP/HTML von unseren Designern für Broschüre-ware Typen WWW-Seiten im Hause verwendet werden. Das Ziel des Systems ist es, Templating in sonst reinem HTML über benutzerdefinierte Tags, die von PHP verarbeitet werden, zu ermöglichen. Zum Beispiel könnte eine Templat-Seite wie folgt aussehen:
<tt:Page template="templates/main.html">
<tt:Content name="leftColumn">
<p> blah blah </p>
...
</tt:Content>
<tt:Content name="rightColumn">
<p> blah blah </p>
...
</tt:Content>
</tt:Page>
Die Vorlage selbst etwas könnte wie folgt aussehen:
<html>
<head>...</head>
<body>
<div style="float:left; width:45%">
<tt:Container name="leftColumn" />
</div>
<div style="width:45%">
<tt:Container name="rightColumn" />
</div>
</body>
</html>
Neben der Seite und Inhalt/Container-Tags, gibt es ein paar andere Tags enthalten im Kern für Dinge wie Flusskontrolle, Iteration über eine Sammlung, Ausgabe dynamischer Werte usw. Das Framework ist so konzipiert, dass es sehr einfach ist, eigene Tags hinzuzufügen, die unter einem anderen Präfix und Namespace registriert sind.
Benutzerdefinierte Tags PHP
Wie analysieren wir diese benutzerdefinierten Tags? Da es keine Garantie dafür gibt, dass die HTML-Datei wohlgeformtes XML ist, sind Lösungen wie XSLT/XPATH nicht zuverlässig. Stattdessen verwenden wir eine Regex, um nach Tags mit registrierten Präfixen zu suchen und diese durch PHP-Code zu ersetzen. Der PHP-Code ist ein Stack-basiertes Design ... wenn ein öffnendes Tag angetroffen wird, wird ein Objekt, das das Tag repräsentiert, auf den Stapel geschoben und seine "Initialisierungsfunktion" (falls vorhanden) wird ausgeführt. Immer wenn ein registriertes schließendes Tag angetroffen wird, wird das letzte Objekt vom Stapel entfernt und seine "Rendering-Funktion" wird ausgeführt.
So, nachdem der Rahmen für die Templat-Tags mit PHP ersetzt, könnte unser Beispiel-Seite wie folgt aussehen (in Objekt es ist ein bisschen hässlicher):
<?php $tags->push('tt', 'Page', array('template'=>'templates/main.html')); ?>
<?php $tags->push('tt', 'Content', array('name'=>'leftColumn')); ?>
<p> blah blah </p>
...
<?php $tags->pop(); ?>
<?php $tags->push('tt', 'Content', array('name'=>'rightColumn')); ?>
<p> blah blah </p>
...
<?php $tags->pop(); ?>
<?php $tags->pop(); ?>
Das Gute, das Schlechte und eval
Nun, wie wird unser neu generierter PHP Code ausgeführt? Ich denke hier an ein paar Optionen. Am einfachsten ist es einfach, eval
die Zeichenfolge, und das funktioniert gut genug. Allerdings wird jeder Programmierer Ihnen sagen: "Eval ist böse, benutze es nicht ...", also lautet die Frage: Gibt es etwas passenderes als eval
, das wir hier verwenden können?
Ich habe überlegt, eine temporäre oder zwischengespeicherte Datei zu verwenden, php://
Ausgabeströme, etc., aber soweit ich sehe, bieten diese keinen wirklichen Vorteil gegenüber eval
. Caching könnte die Dinge beschleunigen, aber in der Praxis sind alle Seiten, die wir zu diesem Thema haben, bereits blitzschnell, daher sehe ich an diesem Punkt keine Notwendigkeit, Geschwindigkeitsoptimierungen vorzunehmen.
Fragen
Für jede der Dinge auf dieser Liste: ist es eine gute Idee? Kannst du dir eine bessere Alternative vorstellen?
- die ganze Idee im Allgemeinen (Custom Tags für html/php)
- Tags PHP-Code statt Verarbeitung direkt
- der Stack-basierter Ansatz
- die Verwendung von
eval
(oder ähnlich) Umwandlung
Vielen Dank für das Lesen und TIA für einen Ratschlag. :)
+1 für eine gut formatierte, gut geschriebene und gut durchdachte Frage. – gpmcadam
Danke. OT: Ich mag deinen Avatar. Gigantor von Evol Intent trug ein T-Shirt mit dem gleichen Design, als er vor ein paar Jahren hier durchkam. Ist es ein Logo für ein Plattenlabel oder etwas oder nur ein zufälliges Design? Ich habe mich das schon seit Jahren gefragt. –