代码之家  ›  专栏  ›  技术社区  ›  Aaron

在PHP中动态创建实例方法

  •  8
  • Aaron  · 技术社区  · 16 年前

    我希望能够在类的构造函数中动态创建实例方法,如下所示:

    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。

    感谢您的帮助。

    2 回复  |  直到 16 年前
        1
  •  18
  •   Gordon Haim Evgi    16 年前

    您正在将匿名函数分配给 财产 ,然后尝试呼叫 方法 属性名。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 = function() { return TRUE; };
    

    见 PHP manual on Anonymous functions 供进一步参考。

        2
  •  3
  •   webbiedave    16 年前

    你可以使用 __call 使用运行时实例方法的神奇方法。

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