doujiu8826 2013-07-01 19:34
浏览 90
已采纳

Php - 动态添加方法不可调用

I have some confusions! I've a simple class as given below

class MyClass {
    public $bar;
}

Then I made an instance

$cls = new MyClass;

Then I've assigned value to my public property $bar from outside of the class

$cls->bar='Bar';

Then I've added new public property $baz and assigned value to it from outside of the class

$cls->baz='Baz';

Then I've added a new public property $showBar and assigned value to it from outside of the class and this time the value is an anonymous function

$cls->showBar = function(){
    return $this->bar;
};

Then I've dumped the $cls using var_dump($cls); instance and output is

object(MyClass)[10]
  public 'bar' => string 'Bar' (length=3)
  public 'baz' => string 'Baz' (length=3)
  public 'showBar' => 
    object(Closure)[11]

Seems that all the public properties are available that I've added including the anonymous function and then I've done

echo $cls->bar; // Bar
echo $cls->baz; // Baz
echo $cls->showBar(); // error

The public property showbar is available in the class (the var_dump shows it) but when I call the function it says

Fatal error: Call to undefined method MyClass::showBar() in D:\xampp\htdocs\phpTutorialInfo\bind\bindtoCls.php on line 234

The question is : It's possible to add new properties after initialization (works fine with a scalar value) and also the showbar seems available then why can't Php recognize it and If it's because it's value is a an anonymous function then why it's available in the var_dump output including the function itself and why Php let me assign the value (anonymous function), it should have thrown an error when I was trying to assign the value of showbar property ? Is that possible at all ?

  • 写回答

3条回答 默认 最新

  • douchensi8625 2013-07-01 19:38
    关注

    You cannot call the function this way. That's because PHP allows to have variables an functions having the same name in a class. If you use the function operator () PHP will only look into the list of functions and don't look at variables that are closures.

    As of PHP5.4 a solution could look like this:

    class MyClass {
    
        public function __call($fname, $args) {
            // bind the `this` scope to use
            $cl = $this->{$fname}->bindTo($this);
            // call the function and pass args to it
            return call_user_func_array($cl, $args);
        }
    
    }
    

    Example:

    $obj = new MyClass();
    $obj->func = function() {
        echo 'We are in ' . get_class($this);
    };
    
    $obj->func(); // We are in MyClass
    

    You can test this here

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据