PHP create_function result stored as instance variable, and called as $object->func()?

456 views Asked by At

I'm using PHPs create_function($args, $code) function to dynamically load a function definition from a database.

The way I'm attempting to implement it is as follows:

I have a class MyClass which has an instance variable myFunction. The constructor populates that instance variable with the result of a call to create_function. I'm hoping to dynamically create a function for the specific object (once instantiated) of this class, that can be called as $object->myFunction(arg1, arg2);

So my class looks like:

class MyClass {

     public $myFunction = '';

     public function __construct() {
         $this->myFunction = //return function body from DB call.
     }


}

I'm then trying to call this dynamic function from elsewhere in my program on the instantiated "MyClass" object by doing something like...

$object = new MyClass();
$object->myFunction(args..); 

However I keep getting errors such as:

MyClass and its behaviors do not have a method or closure named myFunction.

When I run var_dump($object->myFunction) I get back "lambda_xx", which is a good sign meaning create_function is at least working.


Interesting Update on Works vs. Doesn't Work cases

It turns out that in my "other file" where I am doing the following:

   $pm = Yii::app()->user->postMatching; //This is a PostMatching object made elsewhere
    $c = $pm->findRelated;

    foreach ($posts as $post) {

        var_dump($c);

        $postIds = $c($post, $limit);

        //post to related mapping
        $specificRelatedPostIds[$post->postId] = $postIds;

    }
    exit; // exiting for testing

This doesn't work, but if instead of pulling the object $pm from Yii::app()->user->postMatching I just create a new one:

$pm = new PostMatching();
$c = $pm->findRelated; //the anon function instance variable

$c(); // THIS WORKS NOW!

So naturally I var_dumped $pm and $c in both the "newly created" case and the case where I get it from Yii::app()->user->postMatching, and they are identical. The only thing that is different is the name of the anonymous function (as expected).

Does anyone have any idea why this might be the case? In both cases $pm IS an instantiated PostMatching object with that instance variable, I'm just unable to use the syntax to invoke it!


Just updated the above with newly discovered "Twists", thanks guys!

3

There are 3 answers

5
deceze On BEST ANSWER

Maybe something along these lines can be useful:

class MyClass {

     private $myFunction = '';

     public function __construct() {
         $this->myFunction = //return function body from DB call.
     }

     public function myFunction() {
         $args = func_get_args();
         return call_user_func_array($this->myFunction, $args);
     }

}
7
Jon On

That's due to parsing-related troubles that PHP has. This version should work:

$object = new MyClass();
$method = $object->myFunction;
$method(args..); 

See it in action.

0
xdazz On

You can call the method like this:

call_user_func($object->myFunction, args..);