PHP - 我可以将函数名称作为函数参数传递吗?

时间:2012-02-13 13:31:12

标签: 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。

我有点像初学者,我觉得我没见过像我想要的东西。

4 个答案:

答案 0 :(得分: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');
        }
    }
}

对于$ this-> db,要么通过ctor将其传递到Factory,要么也将创建移动到Factory中。它的责任有点加倍,但考虑到本工厂围绕创建数据库相关的协作者图表,这是可以容忍的。

除此之外:是的,call_user_func(array('ClassName', 'methodName'))可行。

参见手册

答案 1 :(得分: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

答案 2 :(得分: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*/

答案 3 :(得分:0)

您可以使用以下方法实现此类行为: