php call_user_func_array and dynamic function calls

Sometimes when you are programming you want to call a specific function, but not directly as a hard coded call but instead using a string or variable for a class/function name.

Here is an example. You have programmed a plugins system that has dynamic loading of your plugins. Each plugin has a static class with various functions. In your framework you want to call a specific function on all loaded plugins. You have an array with all the names of the plugins that are installed in the system. You can use a loop with the variable name with the function call, however for static classes/methods this does not work propertly in php < 5.3. Lets assume you have a function named "filter" that you want to run on a data array. You want each plugin to filter the data array and modify it if necessary.

 
$data = array('a','b','c');
 

As an example, here is one class with a static method:

 
class super_plugin {
    static function filter(&$data) {
        $data[] = 'super';
    }
}
 

As you can see, we want to pass the data array by reference so the plugin can modify it as necessary. For php >= 5.3 you can use:

 
foreach($loaded_plugins as $p)
$p::filter($data);
 

In the above, because the function signature has declared it's argument as a reference, the data array will get 'super' appended to it.

For php < 5.3 this is where call_user_func_array comes in handy.

 
foreach($loaded_plugins as $p)
call_user_func_array(array($p,'filter'),array(&$data));
 

In the above the data is passed as a reference to the filter function. This does not flag the "Deprecated: Call-time pass-by-reference has been deprecated" warning because array() is not a function, and we are not passing &$data as a parameter to a function; instead we are passing an array containing a reference. It's a little trick to get around the warning but still work in php < 5.3.

Comments

Be the first to leave a comment on this post.

Leave a comment

To leave a comment, please log in / sign up