0

I've just recently began messing around with anonymous functions, and I decided to try and put it to actual use in a larger project. After hitting a road block, I tried setting up a small practice script, but the same issue persists. I don't quite understand what's going on, but here's some code,

$a = function($in) {
  echo $in;
};
$a('b4ng');

The above works just fine, as does the following,

class Foo {

    public $cmd;

    public function __construct() {

        $this->cmd = new stdClass();
        $this->cmd->a = 'b4ng';
    }
}

$bar = new Foo();
echo $bar->cmd->a;

That being made clear, the following does not work,

class Foo {

    public $cmd;

    public function __construct() {

        $this->cmd = new stdClass();
        $this->cmd->message = function($in) {

            echo $in;
        };
    }
}

$bar = new Foo();
$bar->cmd->message('b4ng');

When attempting to use the snippet above, I'm hit with the following error,

Fatal error: Call to undefined method stdClass::message()

I understand what the error is telling me, I just don't understand why; 'message' obviously isn't a native function/method of stdClass, but it was declared in 'cmd'.

user1117742456
  • 213
  • 1
  • 3
  • 11
  • 2
    possible duplicate of [Calling closure assigned to object property directly](http://stackoverflow.com/questions/4535330/calling-closure-assigned-to-object-property-directly) - `$bar->cmd->message->__invoke('b4ng');` – FuzzyTree Jul 19 '14 at 04:09
  • @FuzzyTree, thank you, my apologies for not looking around prior to posting this question. In any case, my problem is solved. – user1117742456 Jul 19 '14 at 04:16

2 Answers2

1

There is another thing you can't do:

$o = new SomeClass();
$m = $o->someMethod;
$m();

The issue here is that PHP has a special syntax for a member function call, which is what matches $o->foo(). In your case though, foo is a closure (i.e. a data member, not a method) so that causes the error. In order to fix this, you first need to retrieve foo from your object and then invoke it:

// use brackets to force evaluation order
($o->foo)(args..);
// use dedicated function
call_user_func($o->foo, args..);
// use two steps
$foo = $o->foo;
$foo(args..);

I'd try the first variant first, but I'm not sure if PHP allows it. The last variant is the most cludgy, but that one surely works.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
0

In PHP, you can't define class methods outside the class itself. So, you can't create an instance of stdClass and then dynamically create methods for it.

elixenide
  • 44,308
  • 16
  • 74
  • 100