9

私はオブジェクト指向プログラミングに比較的慣れていません。私は概念をかなり理解していますが、実際には、Zend Framework アプリケーションでモデルを最適に使用する方法に関する情報を見つけるのに非常に苦労しています。

具体的には、データベース テーブルを使用しないモデル (何も拡張しない) があります。ゲッターとセッターを使用して、保護されたメンバーにアクセスします。このモデルをビューに最適に表示する方法に苦労しています。ビュー テンプレートにロジックは必要ありませんが、次のような状況に陥っています。

私のコントローラーで:

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

私のビューテンプレートでは:

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

ビュー テンプレートで関数を呼び出すのはあまり好きではありませんが、これを行うためのより良い方法がわかりません。モデルのメンバーを公開したくありませんが、基本的には同じ結果を達成したいと考えています。

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

モデルに関するすべてを知る必要があるすべての作業をコントローラーに行わせたくありません。

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

Zend Framework でモデルを使用するベスト プラクティスは何ですか? Zend Framework でのこのモデル/ビューのジレンマを理解するのに役立つチュートリアルをお勧めできますか?

4

4 に答える 4

4

1つの可能性は、PHPで魔法の__setメソッドと__getメソッドを使用することです。私は抽象モデルクラス内でそのようにそれらを使用します:

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.
    }
}

これにより、必要に応じてプロパティのゲッターとセッターを指定できるようになりますが、プロパティを返す前に何らかの処理を実行するプロパティだけで、すべてのプロパティに定型関数を定義する必要がなくなります。価値。たとえば、私は多くの場所で機能を使用して、ISO準拠の日付(MySQLに保存されている)をユーザーにとってよりコンパクトで読みやすい形式に変更します。

コントローラーに何を配置するかについては、この投稿を参照して、コントローラー内に配置する処理に関する具体的なフィードバックを確認することをお勧めします。

モデルをビューに自動的にロードし、コントローラー全体をスカートするヘルパーが必要だと感じる人もいます。個人的には、Zend FrameworkとPHPのコンテキスト内では、ビュー内のモデルの状態はリクエストからのモデルに依存することが多いため、コントローラーからビューにモデルを渡すことは十分に理にかなっています(これは確実に処理する必要があります)コントローラ内)。

更新:コメントの批判によると、私が指摘することの1つは、データベースアクセス層とドメイン(またはモデル)層は実際には2つの異なるものですが、ActiveRecordではそれらがブレンドされているということです。私はしばらく前にこの質問をし、この問題についていくつかの有益なフィードバックを受け取りました。モデルで何をするにしても、モデルのデータがどこから来たかに関係なく、すべてのドメインオブジェクトに一貫したAPIを提供する必要があります。

Saemの回答によって提供される1つの利点は、1つ以上のドメインオブジェクトからビューオブジェクトにプロパティ/関数の戻り値を直接マップする機能を提供することだと思います。理論的には、ビュー内の使用法は次のようになります。

// Mapped from Model_User::_data->last_name and Model_User::_data->first_name
$this->name 
于 2009-03-02T22:47:51.777 に答える
3

他の開発者だけがテンプレートを使用する場合は、モデルを渡すことをお勧めします。これは、MVCのモデル ビュー コントローラーの理解に関するジェフ アトウッドの投稿へのリンクです。

于 2009-03-02T21:04:14.210 に答える
3

これは特に zend フレームワークを対象としているわけではありませんが、私の考えでは、問題はかなり一般的です。

コントローラー内でモデルをビューに配線するのではなく、正しい道を進んでいるようです。大量のモデルをマッピングする場合、または同じモデルを何度もマッピングする場合は特に重要です。

簡単なことは、一連のマッピング関数を作成することです。これは、回避していたのが同じものを何度もマッピングすることだけであれば問題ありません。

より一般的な解決策が必要な場合は、ボイラー プレート コードを記述せず、物事をより DRY に保つことにも対処します。マッパー クラスを作成することをお勧めします。

モデルまたはいくつかのモデルを取り、それらをビューにマップする ViewModelMapper を作成できます。

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

次に、これをコントローラーでインスタンス化し、マッピングをセットアップして、コントローラーがマッピングを制御するようにしますが、まれな例外を除いて、すべてのコントローラー マップについて、すべてのボイラー プレートとコーディング ロジックが集中化されます。

于 2009-03-02T21:31:45.593 に答える
1

モデル アーキテクチャの詳細については、この投稿をお読みください。ビューについて具体的に述べているわけではありませんが、一読の価値は間違いなくあります。

getViewClass()モデルに関数を追加することになりました。コントローラーはこの関数を呼び出して、他の方法ではアクセスできない保護された変数を取得します。ビューはゲッターの呼び出しについて心配する必要はありません。

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

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

Zend Framework で作業を完了するためのより良い方法があるかどうかはわかりませんが、これは 1 つの解決策です。

于 2009-03-10T05:14:07.733 に答える