zend udemy tutorial rápido how fácil framework español curso aprende php zend-framework model

php - udemy - Zend Framework: Uso de Modelos y Vistas, mejores prácticas



zend framework curso (4)

Soy relativamente nuevo en la Programación Orientada a Objetos. Entiendo bastante bien los conceptos, pero, en términos prácticos, estoy teniendo dificultades para encontrar información sobre cómo usar mejor los Modelos en mis aplicaciones de Zend Framework.

Específicamente, tengo un modelo (que no extiende nada) que no usa una tabla de base de datos. Utiliza getters y setters para acceder a sus miembros protegidos. Me encuentro luchando con la mejor manera de mostrar este modelo en la vista. No quiero lógica en mis plantillas de vista, pero me encuentro en la siguiente situación:

En mi controlador:

$object = new Object(); $object->setName(''Foo Bar''); $this->view->object = $object;

En mi plantilla de vista:

<h2><?= $this->object->getName() ?></h2>

Realmente no me gusta llamar funciones en mis plantillas de vista, pero no sé una mejor manera de hacerlo. No quiero que los miembros de mi Modelo sean públicos, pero básicamente quiero lograr los mismos resultados:

<h2><?= $this->object->name ?></h2>

No quiero que mi controlador haga todo el trabajo de tener que saber todo sobre el modelo:

$object = new Object(); $object->setName(''Foo Bar''); $this->view->object = $object; $this->view->object->name = $object->getName();

¿Cuál es la mejor práctica de usar modelos en Zend Framework? ¿Alguien puede recomendar algún tutorial que me ayude a entender este dilema de Modelo / Vista en Zend Framework?


Esto no está especialmente orientado al marco Zend, pero el problema es bastante general, en mi opinión.

Parece que estás en el camino correcto, en lugar de cablear el modelo a la vista, dentro del controlador. Prefiere tener ese resumen, especialmente importante si está mapeando una tonelada de modelos, o mapeando el mismo modelo una y otra vez.

Algo simple sería escribir un montón de funciones de mapeo, lo cual estaría bien si todo lo que está evitando es mapear lo mismo una y otra vez.

Si deseaba una solución más general, que también tratara de evitar escribir el código de la placa de la caldera, y mantener las cosas más SECAS, sugiero crear una clase de mapeador.

Podría crear un ViewModelMapper, que tomaría un modelo o algunos modelos y los mapearía a la vista.

class ViewModelMapper { public function __construct($view) { //set the properties } public function addModel($model, $overrideViewProperty = null) { //add the model to the list of models to map, use the view''s property // name to figure out what to map it to? Allow for an override just in case. } public function getMappedView() { //take the view, map all the models } }

Luego podría instanciar esto en su controlador, y configurar las asignaciones, de modo que el controlador controle la asignación, pero toda la placa de la caldera y la lógica de codificación están centralizadas, para todos los mapas de controlador, excepto por raras excepciones.


Si solo otros desarrolladores van a trabajar con las plantillas, recomendaría simplemente pasar los modelos. Aquí hay un enlace a una publicación de Jeff Atwood sobre MVC Understanding Model-View-Controller


Para una buena lectura sobre la arquitectura del modelo, lea esta publicación . No habla específicamente sobre la vista, pero definitivamente vale la pena leerla.

Terminé agregando una función getViewClass() a mis modelos. El controlador llama a esta función para obtener las variables protegidas a las que de otra manera no tendría acceso, y la vista no tiene que preocuparse de llamar a ningún getter.

//controller $object = new Object(); $object->setName(''Foo Bar''); $this->view->object = $object->getViewClass(); //view template <h2><?= $this->object->name ?></h2>

No sé si hay una forma mejor de hacer el trabajo en Zend Framework, pero esta es una solución.


Una posibilidad es usar los métodos mágicos __set y __get en PHP. Los uso como tal dentro de mi clase de modelo abstracto:

abstract class Model_Abstract { protected $_data; // Private Data Members assigned to protected $_data public function __construct($data = null) { // Makes it so that I can pass in an associative array as well as // an StdObject. if(!is_object($data)) { $data = (object) $data; } $this->_data = $data; } public function __get($key) { if (method_exists($this, ''_get'' . ucfirst($key))) { $method = ''_get'' . ucfirst($key); return $this->$method(); } else { return $this->_data->$key; } } public function __set($key, $val) { if ( method_exists( $this, ''_set'' . ucfirst($key) ) ) { $method = ''_set'' . ucfirst($key); return $this->$method($val); } else { $this->_data->$key = $val; return $this->_data->$key; } } } class Model_User extends Model_Abstract { //Example overriding method for the property firstName in the $_data collection. protected function _getFirstName() { // Do some special processing and then output the first name. } }

Esto lo hace para que pueda especificar getters y setters para las propiedades según sea necesario, pero lo hace para que no tenga que definir funciones repetitivas para cada propiedad, solo aquellas en las que desea hacer algún tipo de procesamiento antes de devolver el valor. Por ejemplo, uso la funcionalidad en varios lugares para cambiar las fechas conformes con ISO (como las almacenadas en MySQL) en un formato más compacto y legible para los usuarios.

En cuanto a qué colocar en su controlador, recomendaría mirar esta publicación para obtener algunos comentarios específicos sobre qué manejo colocar dentro de su controlador.

Algunos sienten que preferirían tener un ayudante que automáticamente cargue modelos en la vista y falle el controlador por completo. Personalmente, diría que, en el contexto de Zend Framework y PHP, tiene mucho sentido pasar modelos a la vista desde el controlador porque el estado de los modelos en la vista depende con frecuencia de lo que proviene de la solicitud (que definitivamente debería manejarse). en el controlador).

Actualización: según las críticas en los comentarios, una cosa que señalaría es que su capa de acceso a la base de datos y capa de dominio (o modelo) son realmente dos cosas diferentes, aunque con el Registro activo se combinan entre sí. Hice esta pregunta hace un tiempo y recibí algunos comentarios útiles sobre este asunto. Independientemente de lo que decida hacer con el modelo, querrá proporcionar una API consistente para todos los objetos de dominio, independientemente de dónde provengan los datos para el modelo.

Supongo que uno de los beneficios que ofrece la respuesta de Saem es que ofrece la capacidad de mapear directamente propiedades / valores de retorno de función de uno o más objetos de dominio al objeto de vista. Teóricamente, el uso dentro de la vista se ve así:

// Mapped from Model_User::_data->last_name and Model_User::_data->first_name $this->name