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 ?

有帮助吗?

解决方案

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

其他提示

You cannot add a method dynamically in PHP. What you have done is adding a custom property, which is a function. But this does not makes it a method. To illustrate the difference, you can create a class, with a property & a method with the same name:

class A {
    public $test = 42;
    public test() { return 43; }
}

$a = new A;
$a->test === 42;
$a->test() === 43;

You can use call_user_func. Example:

<?php
class MyClass {
    public $bar;
}
$cls = new MyClass;
$cls->bar='Bar';
$cls->baz='Baz';
$cls->showBar = function() use ($cls) {
    return $cls->bar;
};

echo call_user_func($cls->showBar); // Bar
?>

You may want to define the __call magic method so it may be possible to return $this->bar instead of passing $cls in the closure.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top