php zend-framework zend-form decorator

php - Formularios, decoradores y validación de Zend Framework: ¿debería volver al HTML simple?



zend-framework zend-form (10)

Actualmente estoy trabajando en una aplicación bastante grande que contiene muchos formularios.

Hasta este momento, siempre he estado escribiendo mis formularios a mano y escribiendo mi propia lógica de validación, pero he decidido que ya era hora de que comenzara a usar Zend_Form y sus rutinas de validación integradas.

Sin embargo, sigo tropezando con más y más problemas relacionados con la (falta de) flexibilidad causada por Zend_Form_Decorator . Tareas simples como agregar un botón extra a un solo elemento de entrada se convierten en tareas increíblemente difíciles.

Ahora llegué a un punto en el que considero seriamente Zend_Form_Decorator completo el enfoque Zend_Form_Element + Zend_Form_Decorator , pero no quiero perder las excelentes opciones de validación.

Básicamente, quiero lo mejor de ambos mundos:

  • Escribir formularios de la forma en que los ve el usuario final: en HTML simple
  • Agregue fácilmente validaciones del lado del servidor para formar campos sin romper demasiado el comportamiento estándar de ZF

Una posible solución que estoy considerando es escribir los formularios tanto en el servidor como en las vistas. Esto me permitiría validar fácilmente mis propias formas, pero la desventaja (en mi opinión bastante grande) es que cada forma debería definirse dos veces, lo que simplemente parece completamente incorrecto.

¿Hay alguna guía para hacer esto? ¿Alguno de ustedes ha experimentado lo mismo y, de ser así, cómo ha resuelto estos problemas?

Me gustaría mucho escuchar tus puntos de vista.


Aquí hay algunos decoradores que uso en mis proyectos usando Zend Form. Estos, creo, son lo suficientemente simples de entender.

$stdRowDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'', ''width'' => ''200'')), array(''Label'', array(''escape'' => false, ''class'' => ''zfFormLabel'', ''tag'' => ''td'')), array(array(''row''=>''HtmlTag''), array(''tag''=>''tr''))); $startRowDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'')), array(''Label'', array(''escape'' => false, ''tag'' => ''td'', ''class'' => ''zfFormLabel'')), array(array(''row''=>''HtmlTag''), array(''tag''=>''tr'', ''openOnly''=>true))); $startRowOpenOnlyDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'', ''openOnly''=>true)), array(''Label'', array(''escape'' => false, ''class'' => ''zfFormLabel'', ''tag'' => ''td'')), array(array(''row''=>''HtmlTag''), array(''tag''=>''tr'', ''openOnly''=>true))); $midRowDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'')),array(''Label'', array(''escape'' => false, ''class'' => ''zfFormLabel'', ''tag'' => ''td''))); $midRowCloseOnlyDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'', ''closeOnly''=>''true'')),array(''Label'', array(''escape'' => false, ''class'' => ''zfFormLabel'', ''tag'' => ''td''))); $midRowCloseOnlyNoLabelDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'', ''closeOnly''=>''true''))); $endRowDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'')), array(''Label'', array(''escape'' => false, ''class'' => ''zfFormLabel'', ''tag'' => ''td'')), array(array(''row''=>''HtmlTag''), array(''tag''=>''tr'', ''closeOnly''=>''true''))); $endRowCloseOnlyNoLabelDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'', ''closeOnly''=>''true'')), array(array(''row''=>''HtmlTag''), array(''tag''=>''tr'', ''closeOnly'' => ''true''))); $buttonEndRowDec = array(''ViewHelper'', ''Description'', ''Errors'', array(array(''data''=>''HtmlTag''), array(''tag'' => ''td'', ''colspan''=>''2'', ''align''=>''center'')), array(array(''row''=>''HtmlTag''), array(''tag''=>''tr'', ''closeOnly''=>''true''))); $buttonDecorators = array(''ViewHelper'', array(array(''data'' => ''HtmlTag''), array(''tag'' => ''td'', ''class'' => ''element'')), array(array(''label'' => ''HtmlTag''), array(''tag'' => ''td'', ''placement'' => ''prepend'')), array(array(''row'' => ''HtmlTag''), array(''tag'' => ''tr'')), );


Edite / Comente en la respuesta superior de @Cal Jacobson.

No se puede editar porque el cambio no tiene suficientes caracteres, no se pueden hacer comentarios debido a la insuficiencia de rep pero ...

$this-element->getAction()

debiera ser

$this->element->getAction()

Estoy seguro de que OP lo sabe, pero una corrección evitaría un error al intentar usar el código directamente en la respuesta.


En segundo lugar lo que lo_fye mencionado. En mi experiencia, Zend Forms es torpe y no está bien pensado.

La solución que encontré más fácil y más flexible es crear dos archivos de formulario, 1. la clase de formulario, que inicializa los elementos del formulario, y luego un script de vista para mostrar los elementos del formulario. En mi clase de formulario, apago todos los decoradores, menos el elemento de forma real. por ejemplo: -> removeDecorator (''HtmlTag'') -> removeDecorator (''DtDdWrapper'') -> removeDecorator (''Label'') -> removeDecorator (''Errors'');

Luego, al final del constructor que inicializa los elementos del formulario, pase el script de vista: $ this-> setDecorators (array (array (''ViewScript'', array (''viewScript'' => ''ruta / a / script_form.phtml'')) ));

En el script de visualización, formato el formulario exactamente como me gusta, luego, donde el campo de entrada (por ejemplo) sería simplemente mostrar ese elemento: $ this-> element-> form_element_id. Y note que elimino las decoraciones de error y solo tomo la pila de errores y la visualizo como creo que debería.

La desventaja es que crearía un script de vista para cada formulario o construiría algún tipo de sistema reutilizable usted mismo, así que trabajo extra. Pero al final es mucho más fácil diseñar formas que se ajusten a su diseño, imo.


Esto es lo que aprendí con Zend_Form:

Deja que haga su trabajo, y te ahorrará una tonelada de líneas de código a la larga.

La compensación es que terminas escribiendo más CSS para que las cosas se muestren como quieres. Recuerde, casi cualquier elemento HTML puede ser diseñado para parecerse a cualquier cosa. De forma predeterminada, Zend_Form te ofrece muchos selectores de CSS para obtener lo más específico (o amplio) que necesites. Todavía tengo que ver un caso en el que no pude trabajar los decoradores predeterminados en exactamente lo que quería que fueran.

De acuerdo, tengo un archivo CSS grande y feo, pero en mi experiencia, probablemente sea un archivo CSS grande y feo. Me libero de la preocupación de no preocuparme por la codificación / validación / filtrado / manejo / etc. de formularios específicos de la aplicación, pero me ocupo de algunos elementos específicamente diseñados en un archivo CSS.

Sugerencia si decides seguir esta ruta: asegúrate de utilizar un script de restablecimiento de estilo CSS


He estado utilizando Zend Framework durante aproximadamente un año y solo he usado Zend_Form para uno de mis proyectos (el primero). Zend_Form a Zend_Form después de pasar los 15 minutos intentando posicionar mi enlace ''o Cancelar''. Aunque me encanta la integración.

Ahora uso formularios HTML simples y uso Zend_Filter_Input en el modelo ( Zend_Db_Table en la mayoría de los casos, pero tuve que agregar una capa de servicio en mi último proyecto).

Un fragmento de ejemplo de código de controlador que usa ZFI en el modelo. El manejo de errores y los métodos de validación comunes están en una subclase de Zend_Db_Table y mis clases lo extienden.

Un asistente de visualización formatea la matriz de mensajes de error.

if ($this->_request->isPost()) { $data = $this->_request->getPost(); $event = new Default_Model_DbTable_Event(); $event->createRow($data)->save(); if ($event->hasErrors()) { $this->view->errors = $event->getErrorMessages(); $this->view->event = $data; } else { $this->_redirect(''events''); } }


He estado utilizando tantos componentes Zend como sea posible en los últimos 10 meses, en un proyecto grande, y Zend_Form ha sido el mayor dolor en el ***. Las formas son lentas de renderizar, y difíciles de hacer bonitas. Ni siquiera me inicies en Subformularios. Vi un artículo interesante llamado " scale zend_form " pero no pareció ayudar mucho con la velocidad de renderizado :(

Estoy pensando en hacer que todos mis formularios usen HTML directo en la vista, y solo usar Zend_Form para hacer la validación y el filtrado (no renderizar). O eso, O simplemente usaré Zend_Validate y Zend_Filter, sin el aspecto Formulario en absoluto.

Una herramienta es solo una herramienta si te ayuda. De lo contrario, es solo un obstáculo.


Puede usar Zend Form y generar el HTML usted mismo :) Solo tiene que hacer un seguimiento de los cambios y escuchar los mismos elementos de formulario en HTML y ZF :)


Si desea validadores y filtros sin los formularios: Zend_Filter_Input

22.5. Zend_Filter_Input

Zend_Filter_Input proporciona una interfaz declarativa para asociar múltiples filtros y validadores, aplicarlos a colecciones de datos y recuperar valores de entrada después de que hayan sido procesados ​​por los filtros y validadores. Los valores se devuelven en formato escapado de forma predeterminada para salida segura de HTML.

Aunque - Mi sugerencia personal es aprender a crear decoradores personalizados y ver ayudantes. Zend_Form es muy poderoso, y nunca he tenido problemas tratando de posicionar / decorar cosas. Incluso al construir una tabla compleja de permisos y generar automáticamente columnas y filas usando jQuery, encontré las interfaces Zend_Form un ahorro de tiempo. Si tiene una pregunta específica sobre cómo abordar la decoración de algo, con mucho gusto lo ayudaré. Abra una nueva pregunta y coméntela aquí o algo ...


Yo también encuentro que los decoradores predeterminados son un dolor masivo. Entiendo por qué son así, pero creo que el "factor inconveniente" ha sido subestimado.

De todos modos, recomendaría usar ViewScripts para sus formularios. Tenga en cuenta que estas no son las mismas que las Vistas; en cambio, las ViewScripts se referencian explícitamente en su clase de Formulario, actúan como una "sub-vista" de ordenaciones y le permiten controlar el diseño de cada elemento. Los ejemplos de cómo usar ViewScripts han sido un tanto difíciles de encontrar en el pasado, pero trataré de probar algo útil.

Primero, anule loadDefaultDecorators en su clase de formulario:

public function loadDefaultDecorators() { $this->setDecorators( array( array(''ViewScript'', array(''viewScript'' => ''foo/bar.phtml'') ) ) ); }

Esto hará referencia a un ViewScript llamado bar.phtml ubicado en / views / scripts / foo . Tenga en cuenta las diferencias entre mayúsculas y minúsculas en "ViewScript" y "viewScript" más arriba.

A continuación, tendrá que ajustar los decoradores aplicados a cada elemento para asegurarse de que se muestren pero sin las molestas envolturas dt / dd. Por ejemplo:

$baz = new Zend_Form_Element_Text(''bazInput''); $baz->setDecorators(array(''ViewHelper'',''Errors''));

Finalmente, necesitarás construir tu ViewScript, como por ejemplo:

<form method="post" action="<?php echo $this-element->getAction() ?>"> <table> <tr> <td><label for="bazInput">Baz:</label></td> <td><?php echo $this->element->bazInput ?></td> </tr> </table> <input type="submit" value="Submit Form" /> </form>

Obviamente, este es un ejemplo muy simple, pero ilustra cómo hacer referencia a los elementos del formulario y formar acción.

Luego, en su Vista, simplemente haga referencia y envíe su formulario como de costumbre. De esta forma, puede tener un control mucho más preciso sobre los diseños de sus formularios, para incluir fácilmente agregar Javascript.

Creo que este enfoque resuelve ambos requisitos: puede crear formularios en HTML simple y aún así aprovechar el mecanismo de validación de Zend Form.


Respuesta corta : utilice Zend_Form solo para la validación y el filtrado, y use sus scripts simples antiguos para visualizarlos de la forma que desee.

Respuesta larga : llegué a la conclusión de que no valía la pena usar Zend_Form para generar el HTML del formulario. Al menos en la empresa donde trabajo. ¿Pero por qué?

Es simple, no quiero crear una clase (o usar un truco) solo para "tranquilamente" agregar un enlace dentro de un div dentro de mi formulario. No quiero crear múltiples decoradores solo para agregar funcionalidades que puedan agregarse fácilmente con HTML simple, y lo más importante, los diseñadores que trabajan con nosotros no quieren editar una (o dos o más) clases solo para hacer su trabajo.

Continuamos usando Zend_Form, pero solo para validar y filtrar nuestros formularios. Y no para generarlos.

Sé que muchos no estarán de acuerdo con mis argumentos, pero esa es solo la opinión de alguien que ha tenido noches de insomnio gracias a Zend_Fom.