2017-05-23 6 views
1

静的ビルダを使用してモデルのインスタンスを戻すアクティブ・レコードの実装を考えてみます。ビルダ・メソッドから呼び出されるヒント・メソッドのタイプ

class ModelBuilder { 
    public function __construct($class) { 
     $this->class = $class 
    } 

    private function _execute() { 
     $result = $pdo->query("SELECT * FROM {$this->class}"); 
     return $result->fetchAll(PDO::FETCH_CLASS, $this->class); 
    } 

    public function all() { 
     return $this->_execute(); 
    } 

    public function one() { 
     return $this->_execute()[0]; 
    } 
} 

class Model { 
    public static function builder() { 
     return new ModelBuilder(get_called_class()); 
    } 
} 

class FooModel extends Model { 

} 

を私たちは、このようなFooModelクラスを呼び出すFooのアイテムを取得するには:削除質問に無関係なすべてのコードを、実証するのModelBuilderとモデルクラスのバージョンを軽減ここで非常にある

$foo = FooModel::builder()->one(); 

この場合、インテリジェントIDE(私の場合はPhpStorm)は、どのタイプのオブジェクトが$fooであるかわかりません。オブジェクトを作成するたびに変数/** @var $foo FooModel */をタイプヒントすることができましたが、all()one()メソッドでは、適切なタイプヒントを優先します。

all()one()メソッドに追加する適切なタイプのヒントは何ですか?staticが機能しないことに注意してください。私は、ModelBuilderが呼び出された初期クラスの祖先でなく、builder()メソッドで明示的に呼び出されていると考えています。

このプロジェクトではPHP 5.6を使用していますが、PHP 7固有の回答も歓迎します。

+1

できません。その賞を追加することは、実行可能な唯一の選択肢です。もちろん、私はアクティブなレコードのアンチパターンからもstayong avayをお勧めしますが、それはOOPとSRPに関する私のばかげた考え方です。 –

答えて

1

あなたのモデルはBaseModelのような親クラスを持っている場合 - あなたのようなallone方法、のためのdoc-ブロック内でreturnブロックでBaseModelを使用することができます。

/** 
* @return BaseModel Model instance. 
*/ 
public function one() { 
    return $this->_execute()[0]; 
} 

しかし、この場合には - それがあるだけでBaseModelですY - はないFooModelBooModel ...
あなたは、特定のモデルを持っている目的でのみBaseModelのメソッドとプロパティにアクセスする必要がありますが、具体的なFooModelしない...

/** 
* @method FooModel one Foo model instance. 
*/ 
class FooModel extends BaseModel 
{ 
} 

それとも似DOC-ブロック/** @var $foo FooModel */を使用します。このように、

class FooModel extends BaseModel 
{ 
    /** 
    * @return FooModel Foo model instance. 
    */ 
    public function one() { 
     return parent::one(); 
    } 
} 

やクラスのためのドキュメントブロックを持っています。ouは次のように、適切なDOC-ブロックと子モデルでオーバーライド必要なメソッドを持っていますすでに言及した。

+0

ありがとうございます。実際、 'Model'のプロパティだけでなく、' FooModel'プロパティを利用できる方法を探しています。タイプヒントのために、それぞれの拡張クラスでメソッドをオーバーライドしないようにしたいと思います。私はそれがオーバーライドか、私はdocブロックに固執しなければならないと思います。 – dotancohen

+0

答えを更新しました。例として '@method FooModel one Foo model instance'を追加しました。' FooModel'クラスに対してこのブロックを持つことができるので、 'one'メソッドをオーバーライドする必要はありません。 –

+0

更新していただきありがとうございます。私は、クラスの '@ method'型ヒントについては知らなかったです。ニース!しかし、 'one()'は 'Model'ではなく' ModelBuilder'クラスのメソッドなので、ここでは動作しません。 – dotancohen

関連する問題