How to create a dictionary of functions in PHP?

I want to have a dictionary of functions. Using this dictionary, I could have a handler that takes a function name and an array of arguments, and executes that function, returning a return value if it returns something. The handler throws an error if the name does not match the existing function.

It would be very simple to implement Javascript:

var actions = { doSomething: function(){ /* ... */ }, doAnotherThing: function() { /* ... */ } }; function runAction (name, args) { if(typeof actions[name] !== "function") throw "Unrecognized function."; return actions[name].apply(null, args); } 

But since functions are not first class objects in PHP, I cannot figure out how to do this easily. Is there an easy way to do this in PHP?

+4
source share
6 answers
 $actions = array( 'doSomething' => 'foobar', 'doAnotherThing' => array($obj, 'method'), 'doSomethingElse' => function ($arg) { ... }, ... ); if (!is_callable($actions[$name])) { throw new Tantrum; } echo call_user_func_array($actions[$name], array($param1, $param2)); 

Your dictionary can consist of any valid callable type.

+3
source

I do not understand what do you mean.
If you only need an array of functions:

 $actions = array( 'doSomething'=>function(){}, 'doSomething2'=>function(){} ); 

You can run the function with $actions['doSomething']();

Of course, you may have arguments:

 $actions = array( 'doSomething'=>function($arg1){} ); $actions['doSomething']('value1'); 
+3
source

You can use PHP __call() to do this:

 class Dictionary { static protected $actions = NULL; function __call($action, $args) { if (!isset(self::$actions)) self::$actions = array( 'foo'=>function(){ /* ... */ }, 'bar'=>function(){ /* ... */ } ); if (array_key_exists($action, self::$actions)) return call_user_func_array(self::$actions[$action], $args); // throw Exception } } // Allows for: $dict = new Dictionary(); $dict->foo(1,2,3); 

For static calls, you can use __callStatic() (since PHP5.3).

+2
source
 // >= PHP 5.3.0 $arrActions=array( "doSomething"=>function(){ /* ... */ }, "doAnotherThing"=>function(){ /* ... */ } ); $arrActions["doSomething"](); // http://www.php.net/manual/en/functions.anonymous.php // < PHP 5.3.0 class Actions{ private function __construct(){ } public static function doSomething(){ } public static function doAnotherThing(){ } } Actions::doSomething(); 
+1
source

If you plan to use this in the context of an object, you do not need to create a dictionary of functions / methods.

You can simply cause some error when using a more advanced method using the magic __call() method:

 class MyObject { function __call($name, $params) { throw new Exception('Calling object method '.__CLASS__.'::'.$name.' that is not implemented'); } function __callStatic($name, $params) { // as of PHP 5.3. < throw new Exception('Calling object static method '.__CLASS__.'::'.$name.' that is not implemented'); } } 

Then every other class should extend your MyObject class ...

http://php.net/__call

+1
source

http://php.net/manual/en/function.call-user-func.php

call_user_func will allow you to execute your functions from their names as a string and pass their parameters, but I do not know how this will affect performance, however.

0
source

All Articles