2010-01-08 96 views
4

閱讀this問題後,我不知道是否有人能幫助我瞭解如何實現正確使用這些PHP類依賴注入:依賴注入實現簡單

class DBClass 
{ 
    private $mMysqli; 
    function __construct(mysqli $database) 
    { 
     $this->mMysqli=$database; 
    } 
    function __destruct() 
    { 
     $this->mMysqli->close(); 
    } 

    public function listUsers() 
    { 
     $query='SELECT * FROM Utente;'; 
     $resultset=$this->mMysqli->query($query); 
     while($row = $resultset->fetch_array(MYSQLI_ASSOC)) { 
      echo $row['username']; 
      echo $row['pwd']; 
      echo "<br />\n"; 
     } 

    } 

    public function runQuery($query) 
    { 
     return $resultset=$this->mMysqli->query($query); 
    } 

    public function getConnection() 
    { 
     return $this->mMysqli; 
    } 
} 

會話類:

class Session 
{ 
    private $_session; 
    public $maxTime; 
    private $database; 

    public function __construct(DBClass $database) 
    { 
     $this->database=$database; 
     $this->maxTime['access'] = time(); 
     $this->maxTime['gc'] = get_cfg_var('session.gc_maxlifetime'); 
     session_set_save_handler(array($this,'_open'), 
       array($this,'_close'), 
       array($this,'_read'), 
       array($this,'_write'), 
       array($this,'_destroy'), 
       array($this,'_clean') 
       ); 
     register_shutdown_function('session_write_close'); 
     session_start(); 
     ... 
    } 
} 

用戶類別(有關當前登錄用戶的詳細信息):

class User 
{ 
    private $username; 
    private $role; 
    private $session; 

    function __construct($session) 
    { 
     $this->session=$session; 
     ... 
    } 
} 

外部:

$connection=new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE); 
$database=new DBClass($connection); 
$session=new Session($database); 
$user=new User($session); 

這是正確的方法嗎?

回答

9

是的。您現在通過提供較少耦合的構造函數注入依賴項。您現在可以更輕鬆地換出這些依賴關係,例如當UnitTesting你可以用Mocks替換它們。

儘管使用具體的DBClass作爲TypeHint而不是interface,但您仍然有一些耦合。所以當你想要使用不同的DBClass時,它必須被命名爲DBClass。你可以通過coding against an interface實現更多的鬆散耦合,即具體類必須實現。

要創建一個類的單個實例(如註釋中所述),您可以使用Singleton(如Kevin Peno建議的)或Factory來創建並跟蹤實例是否已創建。或者使用類似於工廠的DI服務容器,但不是同一件事。它爲您創建和管理對象。

Symfony Components library has a Dependency Injection Container具有出色的文檔和關於如何進一步增強與服務容器DI的主題的介紹。容器也可以用來限制實例。一探究竟。

+0

+1對於現有系統/庫 – 2010-01-08 22:10:12

+0

+1對於提及接口 – rick 2010-01-08 22:26:00

+0

感謝您的答案,但我如何使用DI僅實例化對象的一個​​實例,例如數據庫連接? – 2010-01-08 22:39:37