Domanda

Sono relativamente nuovo alla programmazione orientata agli oggetti. Comprendo praticamente i concetti, ma in pratica sto facendo fatica a trovare informazioni su come utilizzare al meglio i modelli nelle mie applicazioni Zend Framework.

In particolare, ho un modello (che non estende nulla) che non utilizza una tabella di database. Utilizza getter e setter per accedere ai suoi membri protetti. Mi trovo alle prese con come visualizzare al meglio questo modello nella vista. Non voglio logica nei miei modelli di visualizzazione, ma mi trovo nella seguente situazione:

Nel mio controller:

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

Nel mio modello di visualizzazione:

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

Non mi piacciono molto le funzioni di chiamata nei modelli di visualizzazione ma non conosco un modo migliore per farlo. Non voglio che i membri della mia modella siano pubblici, ma sostanzialmente voglio ottenere gli stessi risultati:

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

Non voglio che il mio controller faccia tutto il lavoro di dover sapere tutto sul modello:

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

Qual è la migliore pratica nell'uso dei modelli in Zend Framework? Qualcuno può consigliare qualche tutorial che mi aiuterebbe a capire questo dilemma modello / vista in Zend Framework?

È stato utile?

Soluzione

Una possibilità è usare i metodi __set e __get magici in PHP. Li uso così nella mia classe Model astratta:

abstract class Model_Abstract
{
    protected 

Una possibilità è usare i metodi __set e __get magici in PHP. Li uso così nella mia classe Model astratta:

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

Ciò consente di specificare getter e setter per le proprietà come necessario, ma lo rende in modo da non dover definire le funzioni boilerplate per ogni proprietà, ma solo quelle in cui si desidera eseguire una sorta di elaborazione su di essa prima di restituire il valore. Ad esempio, utilizzo la funzionalità in diversi punti per modificare le date conformi ISO (come memorizzate in MySQL) in un formato più compatto e leggibile per gli utenti.

Per quanto riguarda cosa posizionare nel controller, ti consiglio di guardare questo post per un feedback specifico su quale trattamento posizionare all'interno del tuo controller.

Alcuni pensano che preferirebbero avere un aiutante che carica automaticamente i modelli nella vista e schizza del tutto il controller. Personalmente direi che nel contesto di Zend Framework e PHP ha molto senso passare i modelli nella vista dal controller perché lo stato dei modelli nella vista dipende spesso da ciò che proviene dalla richiesta (che dovrebbe sicuramente essere gestita nel controller).

Aggiornamento: In base alle critiche nei commenti, una cosa che vorrei sottolineare è che il livello di accesso al database e il livello di dominio (o modello) sono in realtà due cose diverse, sebbene con Active Record sono mescolati insieme. Ho fatto questa domanda qualche tempo fa e ho ricevuto alcuni utili feedback riguardo questo argomento. Qualunque cosa tu decida di fare con il modello, ti consigliamo di fornire un'API coerente per tutti gli oggetti di dominio indipendentemente dalla provenienza dei dati per il modello.

Suppongo che uno dei vantaggi offerti dalla risposta di Saem sia che offre la possibilità di mappare direttamente proprietà / funzioni restituendo valori da uno o più oggetti di dominio all'oggetto vista. Teoricamente, l'utilizzo all'interno della vista è simile al seguente:

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

Una possibilità è usare i metodi __set e __get magici in PHP. Li uso così nella mia classe Model astratta:

<*>

Ciò consente di specificare getter e setter per le proprietà come necessario, ma lo rende in modo da non dover definire le funzioni boilerplate per ogni proprietà, ma solo quelle in cui si desidera eseguire una sorta di elaborazione su di essa prima di restituire il valore. Ad esempio, utilizzo la funzionalità in diversi punti per modificare le date conformi ISO (come memorizzate in MySQL) in un formato più compatto e leggibile per gli utenti.

Per quanto riguarda cosa posizionare nel controller, ti consiglio di guardare questo post per un feedback specifico su quale trattamento posizionare all'interno del tuo controller.

Alcuni pensano che preferirebbero avere un aiutante che carica automaticamente i modelli nella vista e schizza del tutto il controller. Personalmente direi che nel contesto di Zend Framework e PHP ha molto senso passare i modelli nella vista dal controller perché lo stato dei modelli nella vista dipende spesso da ciò che proviene dalla richiesta (che dovrebbe sicuramente essere gestita nel controller).

Aggiornamento: In base alle critiche nei commenti, una cosa che vorrei sottolineare è che il livello di accesso al database e il livello di dominio (o modello) sono in realtà due cose diverse, sebbene con Active Record sono mescolati insieme. Ho fatto questa domanda qualche tempo fa e ho ricevuto alcuni utili feedback riguardo questo argomento. Qualunque cosa tu decida di fare con il modello, ti consigliamo di fornire un'API coerente per tutti gli oggetti di dominio indipendentemente dalla provenienza dei dati per il modello.

Suppongo che uno dei vantaggi offerti dalla risposta di Saem sia che offre la possibilità di mappare direttamente proprietà / funzioni restituendo valori da uno o più oggetti di dominio all'oggetto vista. Teoricamente, l'utilizzo all'interno della vista è simile al seguente:

<*>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 possibilità è usare i metodi __set e __get magici in PHP. Li uso così nella mia classe Model astratta:

<*>

Ciò consente di specificare getter e setter per le proprietà come necessario, ma lo rende in modo da non dover definire le funzioni boilerplate per ogni proprietà, ma solo quelle in cui si desidera eseguire una sorta di elaborazione su di essa prima di restituire il valore. Ad esempio, utilizzo la funzionalità in diversi punti per modificare le date conformi ISO (come memorizzate in MySQL) in un formato più compatto e leggibile per gli utenti.

Per quanto riguarda cosa posizionare nel controller, ti consiglio di guardare questo post per un feedback specifico su quale trattamento posizionare all'interno del tuo controller.

Alcuni pensano che preferirebbero avere un aiutante che carica automaticamente i modelli nella vista e schizza del tutto il controller. Personalmente direi che nel contesto di Zend Framework e PHP ha molto senso passare i modelli nella vista dal controller perché lo stato dei modelli nella vista dipende spesso da ciò che proviene dalla richiesta (che dovrebbe sicuramente essere gestita nel controller).

Aggiornamento: In base alle critiche nei commenti, una cosa che vorrei sottolineare è che il livello di accesso al database e il livello di dominio (o modello) sono in realtà due cose diverse, sebbene con Active Record sono mescolati insieme. Ho fatto questa domanda qualche tempo fa e ho ricevuto alcuni utili feedback riguardo questo argomento. Qualunque cosa tu decida di fare con il modello, ti consigliamo di fornire un'API coerente per tutti gli oggetti di dominio indipendentemente dalla provenienza dei dati per il modello.

Suppongo che uno dei vantaggi offerti dalla risposta di Saem sia che offre la possibilità di mappare direttamente proprietà / funzioni restituendo valori da uno o più oggetti di dominio all'oggetto vista. Teoricamente, l'utilizzo all'interno della vista è simile al seguente:

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

Ciò consente di specificare getter e setter per le proprietà come necessario, ma lo rende in modo da non dover definire le funzioni boilerplate per ogni proprietà, ma solo quelle in cui si desidera eseguire una sorta di elaborazione su di essa prima di restituire il valore. Ad esempio, utilizzo la funzionalità in diversi punti per modificare le date conformi ISO (come memorizzate in MySQL) in un formato più compatto e leggibile per gli utenti.

Per quanto riguarda cosa posizionare nel controller, ti consiglio di guardare questo post per un feedback specifico su quale trattamento posizionare all'interno del tuo controller.

Alcuni pensano che preferirebbero avere un aiutante che carica automaticamente i modelli nella vista e schizza del tutto il controller. Personalmente direi che nel contesto di Zend Framework e PHP ha molto senso passare i modelli nella vista dal controller perché lo stato dei modelli nella vista dipende spesso da ciò che proviene dalla richiesta (che dovrebbe sicuramente essere gestita nel controller).

Aggiornamento: In base alle critiche nei commenti, una cosa che vorrei sottolineare è che il livello di accesso al database e il livello di dominio (o modello) sono in realtà due cose diverse, sebbene con Active Record sono mescolati insieme. Ho fatto questa domanda qualche tempo fa e ho ricevuto alcuni utili feedback riguardo questo argomento. Qualunque cosa tu decida di fare con il modello, ti consigliamo di fornire un'API coerente per tutti gli oggetti di dominio indipendentemente dalla provenienza dei dati per il modello.

Suppongo che uno dei vantaggi offerti dalla risposta di Saem sia che offre la possibilità di mappare direttamente proprietà / funzioni restituendo valori da uno o più oggetti di dominio all'oggetto vista. Teoricamente, l'utilizzo all'interno della vista è simile al seguente:

<*>

Altri suggerimenti

Se solo altri sviluppatori lavoreranno con i modelli, consiglierei semplicemente di passare i modelli. Ecco un link a un post di Jeff Atwood su MVC Informazioni su Model-View-Controller

Questo non è particolarmente orientato verso il framework zend, ma il problema è piuttosto generale, nella mia mente.

Sembra che tu sia sulla strada giusta, invece di cablare il modello alla vista, all'interno del controller. Preferiresti avere quell'astratto, particolarmente importante se stai mappando una tonnellata di modelli o mappando lo stesso modello ancora e ancora.

Qualcosa di semplice sarebbe scrivere un sacco di funzioni di mappatura, il che andrebbe bene se tutto ciò che stavi evitando è mappare la stessa cosa ancora e ancora.

Se volevi una soluzione più generale, che si occupasse anche di evitare di scrivere quel codice della piastra della caldaia e di mantenere le cose più ASCIUTTE, ti suggerisco di creare una classe mapper.

Potresti creare un ViewModelMapper, che prenderebbe un modello o alcuni modelli e li mapperebbe alla 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
    }
}

È quindi possibile istanziarlo sul controller e impostare i mapping, quindi il controller controlla ancora il mapping, ma tutta la piastra della caldaia e la logica di codifica sono centralizzate, per tutte le mappe del controller, ad eccezione delle rare eccezioni.

Per una buona lettura sull'architettura del modello, leggi questo post . Non parla specificamente della vista, ma vale sicuramente la pena leggerlo.

Ho finito per aggiungere una funzione getViewClass () ai miei modelli. Il controller chiama questa funzione per ottenere le variabili protette a cui altrimenti non avrebbe accesso e la vista non deve preoccuparsi di chiamare alcun getter.

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

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

Non so se esiste un modo migliore per svolgere il lavoro in Zend Framework, ma questa è una soluzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top