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


PHP - Can I pass a function name as a function argument?

>我有两个类,用于访问数据库中的两个不同表。它们都有一个类似的构造函数,如下所示:

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。

有点初学者,我想我从来没有见过我想要的东西。

将代码移动到工厂中创建 DAO,然后注入 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 将其传递到工厂中,要么将创建物也移动到工厂中。这在某种程度上是双重责任,但考虑到这个工厂围绕着创建与数据库相关的协作者图,这是可以容忍的。

除此之外:是的,call_user_func(array('ClassName', 'methodName'))会起作用。请参阅手册

  • http://php.net/call_user_func 和
  • http://php.net/manual/en/language.pseudo-types.php#language.types.callback

首先回答你的问题:不,你不能(不诉诸邪恶代码(将函数名称作为参数传递。但是:您要存档的是使用继承的面向对象方法的典型子问题。

您需要一个基类:

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

仅供记录:邪恶的代码本来是a( 您可以将函数封装在可用作参数的create_function中。b( 您可以将函数名称作为字符串传递给您的函数,然后将其传递给接收函数中的eval

但请记住:当 eval 或 create_function 看起来像答案时,您可能问错了问题!

请参阅:相关问题

如果您觉得有必要将函数名称或函数本身作为函数的参数传递,可以使用几种方法。

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*/

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

  • call_user_func
  • 评估任何文字