即使有关于这个问题的一些讨论,我想检查某些例子什么是最好的方法.
我没有使用现有的解决方案,而是创建了自己的持久层(就像许多人一样)所以我的方法在这里也有问题.
对于db中的每个表,我都有具有适当的getter和setter以及一些必需方法的模型类.我还只创建了一个处理所有类型的模型对象的通用DAO类.
因此,例如,为了保存任何模型对象,我实例化genericDAO类并调用我将模型对象作为属性传递的save方法.问题是在运行时,genericDAO类不知道它获取的whitch模型对象以及它中存在哪些方法(getter和setter),所以我需要调用强制模型类方法,该方法将属性列表检索为多个字符串数组.
例如,对于每个属性,都有数组(table_column_name,attribute_name,is_string).
当我调用save函数时,它看起来像这样:
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]).'();');
...Run Code Online (Sandbox Code Playgroud)
目前我正在使用eval来执行这些方法,但众所周知,eval非常慢.
我正在考虑将其更改为call_user_func方法,
例如:
$voId = call_user_func(array($VO, 'get'.ucfirst($paramIdArray[1])));
Run Code Online (Sandbox Code Playgroud)
但也有其他解决方案.我可以使用这样的东西
$method = 'get'.ucfirst($paramIdArray[1]));
$voId = $VO->$method();
Run Code Online (Sandbox Code Playgroud) 要不然
$method = 'get'.ucfirst($paramIdArray[1]));
$voId = $VO->{$method}();
Run Code Online (Sandbox Code Playgroud)
什么是最好的方式?
首先,没有必要像你一样传递引用.您应该给它一个读取,以尝试理解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();
Run Code Online (Sandbox Code Playgroud)
请注意,没有必要调用method_exists,因为它可能是可调用的,并且由于__get魔术方法支持而不存在...