【问题标题】:Dynamic class method invocation in PHPPHP中的动态类方法调用
【发布时间】:2010-09-20 01:43:01
【问题描述】:

有没有办法为 PHP 动态调用同一类中的方法?我没有正确的语法,但我想做类似的事情:

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

【问题讨论】:

  • 是最初的问题吗?我正在寻找动态调用方法,我发现了这个问题。它与 andy.gurin 给出的语法相同,我没有看到显示问题更新的链接。无论如何...感谢提出并感谢贡献者:-)
  • @Luc - 这是最初的问题。事实证明,当我询问时,我的语法确实是正确的,但是我的代码有其他问题,所以它不起作用。

标签: php


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    这么多年仍然有效!如果它是用户定义的内容,请确保修剪 $methodName。在我注意到它有一个前导空格之前,我无法让 $this->$methodName 工作。

    【讨论】:

    • 如果它是用户定义的内容,请确保您做的不仅仅是修剪名称!比如……安检吧! ;)
    • 在互联网的某个地方,我详细介绍了如何将用户输入的 utf8 转换为 Windows 安全字符。 QuickBooks 让我苦苦思索——为什么 QB 不再是我完成销售的一部分……
    • 你真的允许客户端指定一个输入,动态调用一些方法吗?!我无话可说
    • 显然验证并检查了该类实际上包含这样一个命名方法。有很多方法可以检查该值。它胜过冗长的 switch 语句。
    【解决方案3】:

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

    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 兼容。另一个例子here

    【讨论】:

      【解决方案4】:

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

      $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

      【讨论】:

      • 我想也许我的语法是正确的,所以我的代码有其他问题,因为它不能正常运行。嗯……
      • 对疲倦的人说一句,如果您的方法在对象上被调用并使用 PHPUnit 进行测试,call_user_func_array 就是您的最佳选择。
      • 你我的朋友,拯救了我的一天!我打电话给call_user_func_array($this->$name, ...),想知道为什么它不起作用!
      • 谢谢,这对我有用。 $this->$methodName($arg1, $arg2, $arg3);
      【解决方案5】:

      就我而言。

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

      使用 PHP SOAP。

      【讨论】:

      • 我不确定,但请注意安全问题
      【解决方案6】:

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

      基本上 __call 对动态函数的作用与 __set 和 __get 在 OO PHP5 中对变量的作用一样。

      【讨论】:

        【解决方案7】:

        您也可以使用call_user_func()call_user_func_array()

        【讨论】:

          【解决方案8】:

          省略大括号:

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

          【讨论】:

            猜你喜欢
            • 2014-07-12
            • 2010-09-21
            • 2011-01-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-28
            • 2018-07-08
            • 1970-01-01
            相关资源
            最近更新 更多