2012-02-13 122 views
2

我有兩個類用於訪問我的數據庫中的兩個不同的表。他們都有一個相似的構造,看起來就像是:PHP - 我可以傳遞函數名稱作爲函數參數嗎?

function __construct($db) { 
    $this->db = $db; 
    $userDAO = DAO_DBrecord::createUserDAO($this->db); 
    $this->userDAO = $userDAO; 
} 

其他類有不同之處在於它使用createOtherTableDAO($this->db)相同的構造。

我打算讓其他類這樣的類,如果我可以讓它們全部繼承相同的構造函數,並將createAppropriateTableDAO作爲參數,那將很方便。

爲了澄清,在上面的第一種情況下,createUserDAO($this->db)是一個靜態函數,它調用我的DAO類中的構造函數。在DAO的功能如下所示:

public static function createUserDAO($db) { 
    return new DAO_DBrecord($db, 'users'); 
} 

我用這個方法來確保user模型只能呼籲users表DAO。

我是一個初學者,我不認爲我曾經見過任何我想要的東西。

回答

1

要先回答你的問題:不,你不能(不訴諸於evilCode)傳遞一個函數名作爲參數。 但是:你想存檔的是使用繼承的面向對象方法的海報子問題。

你需要一個基類:

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

和你實現:

class MyClass extends BaseClass 
{ 
    function __construct($db) { 
     parent::__contruct($db); 
     $this->userDAO = DAO_DBrecord::createUserDAO($this->db); 
    } 
} 

只是爲了記錄:在evilCode本來 a)您可以封裝的功能可以用作參數的create_function。 b)您可以將函數名稱作爲字符串傳遞給您的函數,然後將其傳遞給接收函數中的eval

但記住:當eval或create_function看起來像答案,你可能會問錯誤的問題!

請參見:related question

+0

將字符串作爲函數名稱傳遞時,不需要使用eval。 – CBusBus 2012-02-13 14:05:44

+0

爲什麼不直接在父類構造函數中放置一個'switch'並傳遞一個字符串來決定使用哪個dao?那會違反「開放 - 封閉原則」嗎? – JDelage 2012-02-13 14:45:11

+0

此外,我不清楚在子構造函數中寫入'parent :: _ construct($ db)'的好處。爲什麼不簡單地寫'$ this-> db = $ db'(我們根本不需要父構造函數)。這實際上是我現在有我的代碼,但我希望通過在父類中有一個構造函數來簡化它(並且在子項中沒有)。 – JDelage 2012-02-13 14:52:38

2

移動代碼以創建DAO到Factory中,然後注入DAO,而不是將它們硬連接到這些類應該表示的任何內容中。或者相反,在工廠中創建各種表格數據網關(「我用來訪問兩個不同表格的班級」)。

class TableDataGatewayFactory 
… 
    public function create($gatewayName) 
    { 
     switch ($gatewayName) { 
      case 'user': 
       return new TableDataGateway(new UserDao($this->db))); 
       break; 
      default: 
       throw new Exception('No Gateway for $gatewayName'); 
     } 
    } 
} 

至於這個 - $>分貝,無論是傳遞到廠通過構造函數或將創建進廠也是如此。由於該工廠圍繞創建與數據庫相關的協作者圖形,因此責任有所增加,但可以忍受。

除此之外:是的,call_user_func(array('ClassName', 'methodName'))可以工作。見

+0

什麼是工廠? – JDelage 2012-02-13 13:39:57

+0

@JDelage:檢查[this](http://en.wikipedia.org/wiki/Factory_method_pattern)。那裏也有一個PHP例子。 – FtDRbwLXw6 2012-02-13 13:44:11

+0

謝謝,'switch'對我來說應該是顯而易見的...... – JDelage 2012-02-13 14:07:46

1

有幾種方法哪,如果你覺得有必要的功能名稱或確實是函數本身傳遞作爲函數的參數,你可以使用。

call_user_func($function,$args); 

call_user_func是調用它接受一個函數名和可選參數參數方法或函數的PHP的固有功能之一。

call_user_func(當不屬於對象方法時)的功能可以在不使用call_user_func的情況下使用帶有函數名字符串文字的變量進行復制。例如:

function some_func() 
{ 
    echo "I'm a function!"; 
} 

$function = "some_func"; 
$function(); /*Output: I'm a function!*/ 

如果你喜歡冒險的感覺,你可以去遠一點,並通過閉合/匿名函數作爲替代的功能名稱。例如:

$function = function() 
{ 
    echo "I'm another function!"; 
} 

$function(); /*Output: I'm another function*/ 
相關問題