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的

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(); 
    } 
} 

在user.php的,我擴大示範課,但我已經在每一個功能設置的$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(); 
    } 
} 

但它仍然算作依賴注入,因爲我不直接在函數構造函數中調用類。

第二次更新: 讀取多個導遊,這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數據庫對象,或一個postgres數據庫對象,或者誰知道什麼。但只有將對象傳遞給構造函數時纔會發生這種情況。 '公共函數__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的所有優點現在都可以通過'$ this-> db'獲得。但現在,有實例化與靜態,我不熟悉的問題... –

+0

@TimMorton模型只是PDO連接,我只是試圖爲用戶類或任何其他類的連接創建1個連接Model類。你是說因爲我已經擴展了Model類,所以我不需要在用戶構造中注入它? – Craig