Pregunta

Soy relativamente nuevo en la programación orientada a objetos. Entiendo bastante los conceptos, pero en términos prácticos, me está costando mucho encontrar información sobre cómo utilizar 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 sobre cómo mostrar mejor 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>

No me gusta llamar a funciones en mis plantillas de vista, pero no conozco 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 comprender este dilema Modelo / Vista en Zend Framework?

¿Fue útil?

Solución

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

abstract class Model_Abstract
{
    protected 

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

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

Esto hace que pueda especificar getters y setters para propiedades según sea necesario, pero hace que no tenga que definir funciones repetitivas para cada propiedad, solo aquellas en las que desea realizar algún tipo de procesamiento. antes de devolver el valor. Por ejemplo, utilizo la funcionalidad en varios lugares para cambiar las fechas compatibles con ISO (tal como están 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 comentarios específicos sobre qué manejo colocar dentro de su controlador.

Algunos piensan que preferirían tener un ayudante que cargue automáticamente los modelos en la vista y bordee el controlador por completo. Personalmente, diría que dentro del 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 con frecuencia depende de lo que vino de la solicitud (que definitivamente debe manejarse en el controlador).

Actualización: Según las críticas en los comentarios, una cosa que señalaría es que la capa de acceso a la base de datos y la capa de dominio (o modelo) son realmente dos cosas diferentes, aunque con el Registro Activo se mezclan juntos Le pregunté esta pregunta hace un tiempo y recibí algunos comentarios útiles en este asunto. Independientemente de lo que decida hacer con el modelo, querrá proporcionar una API coherente para todos los objetos de dominio, independientemente de dónde provengan los datos del modelo.

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

<*>data; // Private Data Members assigned to protected

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

<*>

Esto hace que pueda especificar getters y setters para propiedades según sea necesario, pero hace que no tenga que definir funciones repetitivas para cada propiedad, solo aquellas en las que desea realizar algún tipo de procesamiento. antes de devolver el valor. Por ejemplo, utilizo la funcionalidad en varios lugares para cambiar las fechas compatibles con ISO (tal como están 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 comentarios específicos sobre qué manejo colocar dentro de su controlador.

Algunos piensan que preferirían tener un ayudante que cargue automáticamente los modelos en la vista y bordee el controlador por completo. Personalmente, diría que dentro del 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 con frecuencia depende de lo que vino de la solicitud (que definitivamente debe manejarse en el controlador).

Actualización: Según las críticas en los comentarios, una cosa que señalaría es que la capa de acceso a la base de datos y la capa de dominio (o modelo) son realmente dos cosas diferentes, aunque con el Registro Activo se mezclan juntos Le pregunté esta pregunta hace un tiempo y recibí algunos comentarios útiles en este asunto. Independientemente de lo que decida hacer con el modelo, querrá proporcionar una API coherente para todos los objetos de dominio, independientemente de dónde provengan los datos del modelo.

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

<*>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

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

<*>

Esto hace que pueda especificar getters y setters para propiedades según sea necesario, pero hace que no tenga que definir funciones repetitivas para cada propiedad, solo aquellas en las que desea realizar algún tipo de procesamiento. antes de devolver el valor. Por ejemplo, utilizo la funcionalidad en varios lugares para cambiar las fechas compatibles con ISO (tal como están 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 comentarios específicos sobre qué manejo colocar dentro de su controlador.

Algunos piensan que preferirían tener un ayudante que cargue automáticamente los modelos en la vista y bordee el controlador por completo. Personalmente, diría que dentro del 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 con frecuencia depende de lo que vino de la solicitud (que definitivamente debe manejarse en el controlador).

Actualización: Según las críticas en los comentarios, una cosa que señalaría es que la capa de acceso a la base de datos y la capa de dominio (o modelo) son realmente dos cosas diferentes, aunque con el Registro Activo se mezclan juntos Le pregunté esta pregunta hace un tiempo y recibí algunos comentarios útiles en este asunto. Independientemente de lo que decida hacer con el modelo, querrá proporcionar una API coherente para todos los objetos de dominio, independientemente de dónde provengan los datos del modelo.

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

<*>data collection. protected function _getFirstName() { // Do some special processing and then output the first name. } }

Esto hace que pueda especificar getters y setters para propiedades según sea necesario, pero hace que no tenga que definir funciones repetitivas para cada propiedad, solo aquellas en las que desea realizar algún tipo de procesamiento. antes de devolver el valor. Por ejemplo, utilizo la funcionalidad en varios lugares para cambiar las fechas compatibles con ISO (tal como están 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 comentarios específicos sobre qué manejo colocar dentro de su controlador.

Algunos piensan que preferirían tener un ayudante que cargue automáticamente los modelos en la vista y bordee el controlador por completo. Personalmente, diría que dentro del 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 con frecuencia depende de lo que vino de la solicitud (que definitivamente debe manejarse en el controlador).

Actualización: Según las críticas en los comentarios, una cosa que señalaría es que la capa de acceso a la base de datos y la capa de dominio (o modelo) son realmente dos cosas diferentes, aunque con el Registro Activo se mezclan juntos Le pregunté esta pregunta hace un tiempo y recibí algunos comentarios útiles en este asunto. Independientemente de lo que decida hacer con el modelo, querrá proporcionar una API coherente para todos los objetos de dominio, independientemente de dónde provengan los datos del modelo.

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

<*>

Otros consejos

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 en MVC Comprensión del Modelo-Vista-Controlador

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. Preferiría 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 estuviera evitando es mapear lo mismo una y otra vez.

Si quería una solución más general, que también abordara evitar escribir ese código de placa de caldera y mantener las cosas más SECAS, sugiero crear una clase de mapeador.

Puede crear un ViewModelMapper, que tomaría un modelo o algunos modelos y los asignarí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
    }
}

Entonces podría crear una instancia de esto en su controlador y configurar las asignaciones, de modo que el controlador aún 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 del controlador, excepto las raras excepciones.

Para una buena lectura sobre la arquitectura del modelo, lee esta publicación . No habla específicamente de 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 otro modo no tendría acceso, y la vista no tiene que preocuparse por 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 mejor manera de hacer el trabajo en Zend Framework, pero esta es una solución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top