5

我想要一本函数字典。有了这个字典,我可以有一个处理程序,它接受一个函数名和一个参数数组,并执行该函数,如果它返回任何内容,则返回它返回的值。如果名称与现有函数不对应,则处理程序将引发错误。

实现 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);
}

但是由于函数在 PHP 中并不是真正的一流对象,所以我不知道如何轻松地做到这一点。有没有一种相当简单的方法可以在 PHP 中做到这一点?

4

6 回答 6

3

我不清楚你的意思。
如果您需要一组函数,只需执行以下操作:

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

你可以运行一个函数$actions['doSomething']();

当然你可以有 args:

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


$actions['doSomething']('value1');
于 2012-06-18T12:11:17.160 回答
3
$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));

您的字典可以包含任何允许的callable类型。

于 2012-06-18T12:13:56.760 回答
2

您可以为此使用 PHP __call()

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);

对于静态调用,__callStatic()可以使用(从 PHP5.3 开始)。

于 2012-06-18T12:13:47.230 回答
1
// >= 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();
于 2012-06-18T12:14:56.157 回答
1

如果您打算在对象上下文中使用它,您不必创建任何函数/方法字典。

您可以使用魔术方法简单地在不存在的方法上引发一些错误__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');
    }
}

然后每个其他类都应该扩展你的MyObject类......

http://php.net/__call

于 2012-06-18T12:25:46.327 回答
0

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

call_user_func将让您将函数的名称作为字符串执行并传递参数,但我不知道这样做对性能的影响。

于 2012-06-18T12:12:01.783 回答