2013-11-24 39 views
3

我正在重新考慮大量代碼以使其更具可測性,並且我擁有一堆依賴於實例化數據庫對象的有用函數。實例化函數中的類是不好的做法PHP

事情是這樣的:

function id_from_name($table, $name) 
{ 
    $db = get_database(); 
    //code that returns an id 
} 

function username_from_user_id($id) 
{ 
    $db = get_database(); 
    //code that returns a username 
} 

還有一堆更像id_exists,id_active等

現在我在想,這是不是做的對象正確的事情或許應該作爲參數傳遞?但是那意味着每次我想要使用這些函數時,都會創建一個新對象並將其發送到每個函數中。

所以真的,我的問題是:我應該將這些函數移動到他們自己的可以訪問數據庫對象的類/庫嗎?並且是我上面通常表現出的一種糟糕的做事方式的例子?

+0

將函數移動到一個類中,然後使用它需要的任何依賴注入該類。 http://en.wikipedia.org/wiki/Dependency_injection – Mark

回答

3

更好的方法確實是做類。並且您將數據庫對象傳遞給構造函數並將其作爲實例變量。這樣每個函數都可以訪問數據庫對象。

現在,爲什麼它被認爲不好實例化例如你的數據庫對象在每個函數中,是因爲如果你決定例如有一天改變你的數據源,你可能需要一個巨大的重構。如果您將數據庫對象傳遞給構造函數,那麼您可以在沒有任何重構的情況下將正確的對象傳入/插入到類中。

...詳細瞭解一下下面DI ...

通過傳遞你的對象到構造函數,你還可以創建一個更清晰的API =>你知道哪些對象依賴於其他的,你知道到底是哪類使用您的DB對象。如果你開始實例化它或者像你所做的那樣在函數內部以靜態方式訪問它,我將不得不查看所有的類來查看你的DB對象的使用位置。還有一點,依賴注入迫使SRP(單一責任原則)=>如果你開始注入過多的對象(構造函數有很多參數),你應該懷疑你的類做得太多了,並開始重構。

0

您可以創建一個類Table_Adapter和實例構造函數內部數據庫對象:

class Table_Adapter 
{ 
    protected $db; 

    public function __construct() 
    { 
     $db = get_database(); 
    } 
} 

然後創建一個子類Items_Table_Adapter' that extends Table_Adapter and put their all methods related to Items`表。

class Items_Table_Adapter extends Table_Adapter 
{ 
    public function item_by_id($id) 
    { 

    } 
} 

然後你使用它像:

$tableAdapter = new Items_Table_Adapter(); 
$item = $tableAdapter->item_by_id(1); 
+0

如果'get_database'沒有傳入'$ db'對象,它是如何工作的? – TomSawyer

0

試着這麼做:

class YourClass{ 

    public static function get_database(){ 
     // your creation 
     return $db; 
    } 

    public function id_from_name($table, $name) 
    { 
     /* your code */ 
     //code that returns an id 
    } 

    public function username_from_user_id($id) 
    { 
     /* your code */ 
    } 

} 

所以你也可以使用這種方式:

$db = YourClass::get_database(); 
$result = $db->id_from_name($table, $name); 
+0

我想他是在談論這個問題:http://kunststube.net/static/ –

0

這當然是建議您可以選擇更換數據基地連接。

現在,如果你的函數get_database()看起來是這樣的:

function get_database() { 
    static $db; 
    if (!$db) 
    $db = new \mysqli(...); 
    return $db; 
} 

那麼你真的,真的應該將其更改爲繞類的包裝,看起來像這樣:

function get_database_manager() { 
    static $dbmgr; 
    if (!$dbmgr) 
    $dbmgr = new DbManager; 
    return $dbmgr; 
} 

function get_database() { 
    return get_database_manager()->getCurrentConnection(); 
} 

其中DbManager有與getCurrentConnection()一起返回的當前連接的實例屬性。如果您想要連接,請執行get_database_manager()->setConnection($newConn)之類的操作。問題解決了:)

我會離開這裏靜態編程的缺點(它在這個線程仍然有許多例子):http://kunststube.net/static/ 以及常用的方法擺脫的那個(我們這裏有另一種方法): http://en.wikipedia.org/wiki/Dependency_injection

相關問題