Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a dictionary of functions in PHP?

I want to have a dictionary of functions. With this dictionary, I could have a handler that accepts a function name and an array of arguments, and executes that function, returning the value it returns if it returns anything. The handler would throw an error if the name does not correspond to an existing function.

This 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 aren't really first class objects in PHP, I can't figure out how to do this easily. Is there a reasonably simple way to do this in PHP?

like image 586
Peter Olson Avatar asked Jun 18 '12 12:06

Peter Olson


4 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 of the allowable callable types.

like image 133
deceze Avatar answered Sep 28 '22 01:09

deceze


I don't clearly get what you mean.
If you need an array of functions just do:

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

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

Of course you can have args:

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


$actions['doSomething']('value1');
like image 39
dynamic Avatar answered Sep 28 '22 01:09

dynamic


You could use PHP's __call() for that:

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 invocations, __callStatic() can be used (as of PHP5.3).

like image 44
Linus Kleen Avatar answered Sep 28 '22 01:09

Linus Kleen


If You plan to use this in object context You do not have to create any function/method dictionary.

You can simply raise some error on unexisting method with magic method __call():

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

like image 37
shadyyx Avatar answered Sep 28 '22 03:09

shadyyx