PHP中的动态类方法调用


87

有没有一种方法可以在PHP的同一类中动态调用方法?我没有正确的语法,但我正在寻找类似的方法:

$this->{$methodName}($arg1, $arg2, $arg3);

这是最初的问题吗?我一直在寻找动态调用方法的方法,但发现了这个问题。它与andy.gurin给出的语法相同,我没有看到显示该问题更新的链接。无论如何...感谢您的提问,并感谢贡献者:-)
Luc M

5
@Luc-这是原始问题。事实证明,当我询问时我确实具有正确的语法,但是我的代码有其他问题,因此它不起作用。
VirtuosiMedia

Answers:


175

有多种方法可以做到这一点:

$this->{$methodName}($arg1, $arg2, $arg3);
$this->$methodName($arg1, $arg2, $arg3);
call_user_func_array(array($this, $methodName), array($arg1, $arg2, $arg3));

您甚至可以使用反射API http://php.net/manual/en/class.reflection.php


我想也许我确实有正确的语法,所以我的代码有其他问题,因为它无法正常运行。嗯...
VirtuosiMedia

如果在对象上调用您的方法并用PHPUnit测试您的方法,那么请耐烦call_user_func_array
好的,请确定

你我的朋友,刚刚拯救了我的一天!我正在打电话call_user_func_array($this->$name, ...),想知道为什么它不起作用!
Pubudu Dodangoda


10

您可以在PHP中使用重载: 重载

class Test {

    private $name;

    public function __call($name, $arguments) {
        echo 'Method Name:' . $name . ' Arguments:' . implode(',', $arguments);
        //do a get
        if (preg_match('/^get_(.+)/', $name, $matches)) {
            $var_name = $matches[1];
            return $this->$var_name ? $this->$var_name : $arguments[0];
        }
        //do a set
        if (preg_match('/^set_(.+)/', $name, $matches)) {
            $var_name = $matches[1];
            $this->$var_name = $arguments[0];
        }
    }
}

$obj = new Test();
$obj->set_name('Any String'); //Echo:Method Name: set_name Arguments:Any String
echo $obj->get_name();//Echo:Method Name: get_name Arguments:
                      //return: Any String


3

如果您正在PHP中使用类,那么我建议您在PHP5中使用重载的__call函数。您可以在此处找到参考。

基本上,__call对动态函数起作用,而__set和__get对OO PHP5中的变量起作用。


2

这些年来仍然有效!如果是用户定义的内容,请确保修剪$ methodName。我无法使$ this-> $ methodName起作用,直到我注意到它有一个前导空间。


如果是用户定义的内容,请确保您所做的不仅仅是修饰名称!如...安全检查!;)
Erk

在互联网上的某个地方,我详细介绍了如何将用户输入的utf8转换为Windows安全字符。QuickBooks令我心烦意乱-以及为什么QB不再是我完成销售的一部分...
Chris K

您是否真的允许客户端指定一个可以动态调用某些方法的输入?我
无话可说

显然已验证并检查了该类是否实际包含此类命名方法。有很多方法可以检查该值。它击败了冗长的switch语句。
Snapey

1

就我而言。

$response = $client->{$this->requestFunc}($this->requestMsg);

使用PHP SOAP。


2
我不确定,但是要注意安全问题
tom10271 '16

1

您可以使用闭包将方法存储在单个变量中:

class test{        

    function echo_this($text){
        echo $text;
    }

    function get_method($method){
        $object = $this;
        return function() use($object, $method){
            $args = func_get_args();
            return call_user_func_array(array($object, $method), $args);           
        };
    }
}

$test = new test();
$echo = $test->get_method('echo_this');
$echo('Hello');  //Output is "Hello"

编辑:我已经编辑了代码,现在它与PHP 5.3兼容。这里的另一个例子

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.