9

Just wondering why something like this doesn't work:

public function address($name){
    if(!isset($this->addresses[$name])){
        $address = new stdClass();
        $address->city = function($class = '', $style = ''){
            return $class;
        };          
        $this->addresses[$name] = $address;
    }
    return $this->addresses[$name];
}

Calling it like echo $class->address('name')->city('Class') should just echo Class, however I get Fatal error: Call to undefined method stdClass::city()

I can find a better way to do this, because this will get messy, but I'm wondering what I might be doing wrong there, or if PHP doesn't support this and why.

Kavi Siegel
  • 2,964
  • 2
  • 24
  • 33

3 Answers3

9

PHP is right when invoke fatal error Call to undefined method stdClass::city() because object $class->address('name') has no method city. Intead, this object has property city which is instance of Closure Class (http://www.php.net/manual/en/class.closure.php) You can verify this: var_dump($class->address('name')->city)

I found the way to call this anonymous function is:

$closure = $class->address('name')->city;
$closure('class');

Hope this helps!

Sergey Ratnikov
  • 1,296
  • 8
  • 12
5

Sadly it is not possible within stdClass, but there is a workaround -- PHP Anonymous Object.

// define by passing in constructor
$anonim_obj = new AnObj(array(
    "foo" => function() { echo "foo"; }, 
    "bar" => function($bar) { echo $bar; } 
));

$anonim_obj->foo(); // prints "foo"
$anonim_obj->bar("hello, world"); // prints "hello, world"
Community
  • 1
  • 1
Mihailoff
  • 577
  • 5
  • 6
2

AFAIK, this is not supported by PHP, and you must use the call_user_func() or call_user_func_array() functions to call closures assigned to class properties (usually you can use __call() to do this, but in your case, the class is stdClass, so this isn't possible).

FtDRbwLXw6
  • 27,774
  • 13
  • 70
  • 107