Zend_Db_ActiveRecordの例での擬似静的メソッドの使用

Zend Frameworkをマスターしている間に、可能な限りRailsに似た機能の観点からZend_ActiveRecordコンポーネントを作成することにしました。 zendaコミュニティでも同様の提案がありましたが、長い間更新されておらず、__ callStatic()のためにphp 5.3が必要でした。 この事実は私には不向きでしたが、静的としてモデルクラスの動的メソッドを呼び出す必要性は依然として非常に重要なトピックのままですが、私はzendの自分のActiveRecordの例だけでそれを理解しようとしました



ブログエントリのテーブル(またはサービス)を表すPostモデルがあるとします。



クラスPostはZend_ActiveRecord_Abstractを拡張します{}




次のように検索することは論理的で便利です。



投稿:: find( 'all');




したがって、検索メソッドへのアクセスが必要になるたびにモデルをインスタンス化する必要がなくなります。 一見すると、このメソッドを静的として説明するだけで十分なように思えますが、! 静的メソッドが呼び出されると、コンストラクターは呼び出されず、モデルを動作状態にするためにロジックによってメイン関数を実装する必要があります。 たとえば、ActiveRecordパターンの主な利点の1つは、依存モデル、つまり関連付けの整合性と柔軟な使用です。したがって、たとえば、コメントを投稿に追加し、すべての投稿と関連コメントを検索してみましょう。 Railsでは、次のようになります。



クラスPost <ActiveRecord :: Base

has_many:コメント

終わり



クラスComment <ActiveRecord :: Base

belongs_to:投稿

終わり



Post.find:all ,: include =>:コメント





Railsのhas_manyとbelongs_toは、アソシエーションを登録するためのメソッドであり、phpと同様に次のようになります。



クラスPostはZend_ActiveRecord_Abstractを拡張します{

//初期化のために別の関数を選択します、なぜなら PHPで

//静的呼び出しのデフォルトコンストラクターはありません

保護された静的関数initialize(){

//コメント-Railsのように複数形で、

//このパラメータはインフレクタによって処理されるため、恥ずかしくないでください

self :: has_many( 'comments');

}

}



クラスComment extends Zend_ActiveRecord_Abstract {

保護された静的関数initialize(){

self :: belongs_to( 'post');

}

}



//検索

Post :: find(array( 'all'、 'include' => 'comments'));



最初に注目するのは、静的メソッドを使用して関連付けを宣言する必要があるということです。 これが必要なのは、静的検索を呼び出す段階ではクラスのインスタンスがなく、初期化子はデフォルトのコンストラクターからではなく、find()から手動で呼び出す必要があるためです。これは、特に初期化本体で他の関数デフォルトは、クラスのインスタンスの存在を意味します。 例えば



クラスPostはZend_ActiveRecord_Abstractを拡張します{

関数初期化{

self :: has_many( 'comments');



//たとえば、オブジェクトの初期化日を設定します

$ this-> set_attribute( 'initialized_at'、timestamp());



}

}





静的呼び出しでは、これにより致命的なエラーが発生します。



クラスの既に作成されたインスタンスからfindを呼び出す必要がある場合もあります



// id = 1のフィードを投稿します

$ post = new Post(1);



//何かの検索を呼び出します

$ something = $ post-> find(array( 'all'、 'conditions' => array(......));



//コメントを投稿にアップロードするか、デフォルトですでに作成されているCommentモデルのfindメソッドが呼び出されます

$ otherthing = $ post-> comments-> find(array( 'all'));



これはすべて、モデルのライフサイクルのさまざまな時点で、静的またはその他の方法でメソッドがどのように呼び出されたかを知る必要があるという事実につながります。 解決策が見つかりました:findメソッドをデフォルトでNOT STATICとして暗示し、静的に呼び出すことを妨げませんが、静的呼び出しでクラスの一時インスタンスを作成します。 PHP自体は、便利な1行のメソッドを提案しました。



クラスZend_ActiveRecord_Abstract {



public function find($ options = array()){

// $ thisの存在によって呼び出しのタイプを決定します。 静的コンテキストでは、変数は定義されていません

if(!isset($ this))$ This = new self(); else $ This = $ this; // $ thisと$ Thisは異なる変数です

//さらに、結果を考えずにオブジェクトを操作しますが、$ thisの代わりに$ Thisを使用します

$ This-> mehod();

...

}

}





または、ストラップを使用することができます



クラスZend_ActiveRecord_Abstract {

public static funtion get_instance(){

$ obj = new self();

return $ obj;

}



public funtion find($ options = array()){

if(!isset($ this))return self :: get_instance()-> find($ options);

//さらに通常どおり動作します

}



}





この呼び出しでは、疑似静的メソッド自体で、残りのコードで使用するには不便なアクションをエミュレートするだけです。 つまり この場合、呼び出し



$ post_instance = new Post();

$ post_instance-> find();



そして

投稿:: find();





完全に同一ですが、後者の場合、毎回クラスのインスタンスを作成する必要はありません



All Articles