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