【问题标题】:Dynamically Create Instance Method in PHP在 PHP 中动态创建实例方法
【发布时间】:2011-03-14 23:12:49
【问题描述】:

我希望能够像这样在类的构造函数中动态创建实例方法:

class Foo{
   function __construct() {
      $code = 'print hi;';
      $sayHi = create_function( '', $code);
      print "$sayHi"; //prints lambda_2
      print $sayHi(); // prints 'hi'
      $this->sayHi = $sayHi; 
    }
}

$f = new Foo;
$f->sayHi(); //Fatal error: Call to undefined method Foo::sayHi() in /export/home/web/private/htdocs/staff/cohenaa/dev-drupal-2/sites/all/modules/devel/devel.module(1086) : eval()'d code on line 12 

问题似乎是 lambda_2 函数对象没有在构造函数中绑定到 $this。

感谢任何帮助。

【问题讨论】:

  • 你可能想清理构造函数代码中的错误。

标签: php oop dynamic


【解决方案1】:

您将匿名函数分配给属性,但随后尝试使用属性名称调用方法。 PHP 不能自动从属性中取消引用匿名函数。以下将起作用

class Foo{

   function __construct() {
      $this->sayHi = create_function( '', 'print "hi";'); 
    }
}

$foo = new Foo;
$fn = $foo->sayHi;
$fn(); // hi

您可以利用神奇的__call 方法拦截无效的方法调用,以查看是否有属性持有回调/匿名函数:

class Foo{

   public function __construct()
   {
      $this->sayHi = create_function( '', 'print "hi";'); 
   }
   public function __call($method, $args)
   {
       if(property_exists($this, $method)) {
           if(is_callable($this->$method)) {
               return call_user_func_array($this->$method, $args);
           }
       }
   }
}

$foo = new Foo;
$foo->sayHi(); // hi

从 PHP5.3 开始,您还可以使用

创建 Lambda
$lambda = function() { return TRUE; };

请参阅PHP manual on Anonymous functions 以获取更多参考。

【讨论】:

  • 为了完整起见,以这种方式使用 create_function 将在每次构造类时在全局空间中创建一个 lamda 函数,并且将保留在内存中而没有垃圾收集的好处(例如当对象未设置时) .它会起作用,但要小心使用。
  • 为了更加完整,create_function 不会创建类似 lambda 的任何东西 - 它基本上是一个美化的 eval,它创建了一个名为的函数,因此没有“真正的”函数可能会发生冲突。除非您需要与 PHP
【解决方案2】:

您可以使用__call 魔术方法来使用运行时实例方法。

class Foo
{
    public function __call($name, $args) 
    {
        if ($name == 'myFunc') {
            // call myFunc
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 2017-04-26
    相关资源
    最近更新 更多