generalPHP - creación de plantillas con etiquetas personalizadas - ¿este es un uso legítimo de eval?
A finales del 2009, escribí un sencillo sistema de plantillas para PHP/HTML para ser utilizado internamente por nuestros diseñadores de páginas web tipo folleto-ware. El objetivo del sistema es permitir la creación de plantillas en HTML, por lo demás puro, a través de etiquetas personalizadas que PHP procesa. Por ejemplo, una página de plantilla podría tener este aspecto:
<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>
la propia plantilla podría ser algo como esto:
<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>
Además de la página y las etiquetas de contenido/el recipiente, hay algunas otras etiquetas incluidas en el núcleo para cosas como control de flujo, iterar sobre una colección, generar valores dinámicos, etc. El marco está diseñado por lo que es muy fácil agregar su propio conjunto de etiquetas registradas bajo otro prefijo y espacio de nombres.
etiquetas personalizadas para PHP
¿Cómo podemos analizar sintácticamente estas etiquetas personalizadas? Como no hay garantía de que el archivo HTML esté bien formado en XML, las soluciones como XSLT/XPATH no serán confiables. En cambio, usamos una expresión regular para buscar las etiquetas con prefijos registrados, y las reemplazamos con código PHP. El código PHP es un diseño basado en pila ... al encontrar una etiqueta de apertura, un objeto que representa la etiqueta se crea insertado en la pila y se ejecuta su "función de inicialización" (si corresponde). Cada vez que se encuentra una etiqueta de cierre registrada, el objeto más reciente se saca de la pila y se ejecuta su "función de representación".
Así, después de que el marco sustituye a las etiquetas de plantillas con PHP, nuestra página de ejemplo podría ser algo como esto (en bienes raíces es un feo bits):
<?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(); ?>
El bueno, el malo, y eval
Ahora, ¿cómo ejecutar nuestro código PHP recién generado? Puedo pensar en algunas opciones aquí. Lo más fácil es simplemente eval
la cadena, y eso funciona bastante bien. Sin embargo, cualquier programador le dirá "eval es malo, no lo use ..." entonces la pregunta es, ¿hay algo más apropiado que eval
que podamos usar aquí?
He considerado utilizar un archivo temporal o en caché, usando php://
flujos de salida, etc., pero hasta donde puedo ver, estos no ofrecen ninguna ventaja real sobre eval
. El almacenamiento en caché puede acelerar las cosas, pero en la práctica todos los sitios que tenemos sobre este tema ya son increíblemente rápidos, así que no veo la necesidad de optimizar la velocidad en este punto.
Preguntas
Para cada una de las cosas en esta lista: ¿Es una buena idea? ¿Puedes pensar en una mejor alternativa?
- toda la idea en general (etiquetas personalizadas para HTML/PHP)
- conversión de etiquetas de código php en lugar de procesamiento directamente
- el enfoque basado en la pila
- el uso de
eval
(o similar)
Gracias por la lectura y la TIA para cualquier consejo. :)
+1 para una pregunta bien formateada, bien escrita y bien pensada. – gpmcadam
Gracias. OT: me gusta tu avatar. Gigantor de Evol Intent llevaba una camiseta con ese mismo diseño exactamente cuando llegó aquí hace unos años. ¿Es un logotipo para una disquera o algo así, o simplemente un diseño al azar? Me he estado preguntando eso por años. –