0

私は依存性注入の使い方を理解するのに苦労しています。私はここでたくさんの質問/回答を読んだことがありますが、私が使用しているコードでは描けません。PDOと依存関係注入の使い方

Model.phpは

abstract class Model { 

    protected static function getDB() { 
     static $db = null; 

     if ($db === null) { 
      $db = new PDO('mysql:host=host;dbname=dbname;charset=utf8', 'dbuser', 'password'); 
     } 

     return $db; 
    } 
} 

model.phpはちょうど私が設定し、それが静的に呼び出しから脱却したいという関数が含まれています。 user.phpに

User.php

class User extends Model { 

    /* 
    * Selects all of the user information 
    */ 
    public function getUser($id){ 

     $db = static::getDB(); 

     $sth = $db->prepare('SELECT * FROM user WHERE id = :id'); 
     $sth->bindValue(':id', $id, PDO::PARAM_INT); 
     $sth->execute(); 

     return $sth->fetch(); 
    } 

    /* 
    * Selects all of the user posts 
    */ 
    public function getUserPosts($id){ 
     $db = static::getDB(); 

     $sth = $db->prepare('SELECT * FROM user_posts WHERE user_id = :id'); 
     $sth->bindValue(':id', $id, PDO::PARAM_INT); 
     $sth->execute(); 

     return $sth->fetch(); 
    } 
} 

私はモデルクラスを拡張するんだけど、一つ一つの機能に$db = static::getDB();を設定しました。

私は依存性注入がメソッド/変数をオブジェクトに渡すだけであることを知っていますが、私はこのことを正しく行っているかどうかもわかりません。

私はプライベート変数を作成する方が良いだろうと思っていますし、コンストラクタで私たちはそうのようなgetDB()を呼びたい:

class User extends Model { 

    protected $db; 

    public function __construct(){ 
     $this->db = getDB(); 
    } 

    /* 
    * example usage 
    */ 
    public function getUser($id){ 
     $sth = $this->db->prepare('SELECT * FROM user WHERE id = :id'); 
     $sth->bindValue(':id', $id, PDO::PARAM_INT); 
     $sth->execute(); 

     return $sth->fetch(); 
    } 
} 

さらに思考を更新

しかし、私は関数コンストラクタで直接クラスを呼び出すわけではないので、それは依然依存関係注入としてカウントされますか?

SECOND UPDATE:複数のガイドを読んだ後 、このpage多くの意味を作る巻き上げ、これは私が思い付いたものです。

model.php

abstract class Model { 
    protected $db = null; 

    public function __construct(){ 
     if($this->db === null){ 
      try { 
       $this->db = new PDO('mysql:host=' . Config::DB_HOST . ';dbname=' . Config::DB_NAME . '; charset=utf8', Config::DB_USER, Config::DB_PASSWORD); 
       $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      } catch (PDOException $e) { 
       echo 'Connection failed: ' . $e->getMessage(); 
      } 
     } 
     return $this->db; 
    } 
} 

User.php

class User extends Model { 

    protected $db; 

    public function __construct(Model $db){ 
     $this->db = $db; 
    } 

    /* 
    * example usage 
    */ 
    public function getUser($id){ 
     $sth = $this->db->prepare('SELECT * FROM user WHERE id = :id'); 
     $sth->bindValue(':id', $id, PDO::PARAM_INT); 
     $sth->execute(); 

     return $sth->fetch(); 
    } 
} 

どのようにそれが見えますか?

+0

依存性注入の美しさは、クラスがストレージに使用されているものなどを知る必要がないことです。あなたはそれをmysql dbオブジェクト、またはpostgres dbオブジェクト、または誰が何を知っているかに渡すことができます。しかし、それはコンストラクタにオブジェクトを渡す場合にのみ発生します。 'パブリック関数__construct($ dbObject){$ this-> db = new $ dbObject; } '私は静的なオブジェクト(私は離れている)について話しているわけではありませんが、依然依存*注入*があることを理由にそれはまだ実際に注入*しなければなりません。 –

+0

あなたはDIを使用していません – OsDev

+0

@OsDev質問を更なる情報で更新しました – Craig

答えて

1

実際に依存関係をモデルに供給していないため、依存関係注入を使用していないと思うのですが、コンストラクタで生成しています。あなたはコンストラクタに引数として渡す必要がある依存性を供給するために

public function __construct($db){ 
    $this->db = $db; 
} 

あなたのクラスからの接続の作成を分離し、依存性の注入の利点を使用することができます。この方法で、実際のものの代わりにテスト用のMockオブジェクトを渡すようなものです。

+0

あなたの答えを見てから、より多くのことを探し始めました。更新された質問はどうやって見えますか? – Craig

+0

@Johnson 'User'が' Model'を拡張するのはなぜですか?コンストラクターでDIを介してModelを渡しています。 Modelのすべての良さは、 '$ this-> db'を通して利用可能になりました。しかし、今、私はよく知られていないインスタンス化されたvs静的​​な問題があります。 –

+0

@TimMortonモデルはちょうどPDO接続です。私は、ユーザークラスまたは拡張する他のクラスに対して1つの接続を作成しようとしていますModelクラス。私は既にModelクラスを拡張して以来、私はそれをユーザー構造に注入する必要はないと言っていますか? – Craig

関連する問題