Php(eval vs call_user_func vs变量函数......)

时间:2011-02-04 16:16:38

标签: php

即使有关于这个问题的一些讨论,我想检查某些例子,哪种方法最好 我没有使用现有的解决方案,而是创建了自己的持久层(就像许多人一样) 所以我的方法在这里也有问题。

对于db中的每个表,我都有具有适当的getter和setter以及一些必需方法的模型类。我还只创建了一个处理所有类型模型对象的通用DAO类 因此,例如,为了保存任何模型对象,我实例化genericDAO类并调用我将模型对象作为属性传递的save方法。 问题是在运行时,genericDAO类不知道它得到的whitch模型对象以及它中存在哪些方法(getter和setter),所以我需要调用强制模型类方法来检索属性列表作为多个字符串数组。
例如,对于每个属性,都有数组(table_column_name,attribute_name,is_string)。

当我调用保存功能时,它看起来像这样:

public function save(&$VO) {  
$paramArray = $VO->getParamArray();//get array of attributes
$paramIdArray = $paramArray[0];  //first attribute is always id
/*create and execute getId() and store value into $void to check if it's save or update*/
eval('$voId = $VO->get'.ucfirst($paramIdArray[1]).'();');  
...

目前我正在使用eval来执行这些方法,但众所周知,eval非常慢 我正在考虑将其更改为call_user_func方法
类似的东西:

$voId = call_user_func(array($VO, 'get'.ucfirst($paramIdArray[1])));

但也有其他解决方案。我可以使用这样的东西

$method = 'get'.ucfirst($paramIdArray[1]));
$voId = $VO->$method();
或者

$method = 'get'.ucfirst($paramIdArray[1]));
$voId = $VO->{$method}();

最好的方法是什么?

2 个答案:

答案 0 :(得分:8)

首先,没有必要像你一样传递引用。您应give this a read尝试了解PHP如何处理对象引用。

因此public function save(&$VO) {应该成为public function save($VO) {

其次,没有必要使用eval(事实上,最好不要因为速度,可调试性等)。您无法像动态的那样堆叠跟踪eval来电。

第三,call_user_func几乎没用,因为PHP支持动态变量函数。而不是call_user_func(array($obj, $method), $arg1),只需致电$obj->$foo($arg1)即可。 call_user_func_array函数仍然有用,因为它支持可变长度参数并支持传递引用。

所以,最终,我会建议:

$method = 'get' . ucfirst($paramIdArray[1]);
$voId = $VO->$method();

请注意,无需调用method_exists,因为它可能是可调用的,并且由于__get魔术方法支持而不存在...

答案 1 :(得分:2)

我通常会使用:

$method = 'get'.ucfirst($attribute);
if(method_exists($obj, $method){
  $obj->$method();
} 

但除非有一个很好的理由我会从key => value返回一个getParamArray数组。并使用它而不是使用吸气剂......