我有这个功能:
///////////////////////////////////////////////////////////////
public static function make_table( $inputList, $funcArray ,$fieldArray){
$i = 0;
$result = Array();
foreach($inputList as $element){
$j = 0;
foreach($funcArray as $function){
$result[$i][$fieldArray[$j]] = $element->$function();
$j++;
}
$i++;
}
return $result;
}
其中inputList是Ticket_Reply项的列表(包含类ticket_content的实例变量。)funcArray是要执行的函数列表。
////////////////////////////////////////// 我这样执行:
$result['ticket_replies'] = make_table($entire_ticket['reply_array'], Array("getTReplyId","getContent()->getContent","getTimestamp"), Array("tReplyId","replyContent","timestamp"));
传递getContent() - > getContent时我尝试执行的操作是执行Ticket_Reply对象的getContent,它返回ticket_content对象,然后对返回的对象执行getContent以返回表示内容的文本。
////////////////////////////////////////// //如果我用函数数组
执行它Array("getTReplyId","getContent()","getTimestamp")
而不是
Array("getTReplyId","getContent()->getContent","getTimestamp")
然后我的输出由print_r找到:
Array ( [0] => Array ( [tReplyId] => 1 [replyContent] => Ticket_Content Object ( [tContentId:Ticket_Content:private] => 1 [content:Ticket_Content:private] => ik krijg het spel niet installed! [db] => Array ( [host] => localhost [port] => 3306 [name] => ryzom_ams_lib [user] => root [pass] => xxxxxx ) ) [timestamp] => 2013-07-08 14:47:19 ) [1] => Array ( [tReplyId] => 5 [replyContent] => Ticket_Content Object ( [tContentId:Ticket_Content:private] => 5 [content:Ticket_Content:private] => Help he got hacked! [db] => Array ( [host] => localhost [port] => 3306 [name] => ryzom_ams_lib [user] => root [pass] => xxxxxx ) ) [timestamp] => 2013-07-09 00:48:17 ) )
正如你所看到的,replyContent是类ticke_content的一个对象,而类ticket_content提供了一个函数getContent,所以我猜想$ funcArray中的getContent() - > getContent会执行对象的getContent,但是相反,它会发出警告:
Fatal error: Call to undefined method Ticket_Reply::getContent()->getContent()
其中Ticket_Reply是inputList
的实际对象的类的名称现在有人告诉我使用call_user_func_array,我试过了,但没有取得多大成功。
public static function make_table( $inputList, $funcArray ,$fieldArray){ $i = 0; $result = Array(); foreach($inputList as $element){ $j = 0; foreach($funcArray as $function){ $result[$i][$fieldArray[$j]] = call_user_func_array(array_merge(array($element), $function),array()); $j++; } $i++; } return $result; }
与params:
make_table($entire_ticket['reply_array'], Array(Array("getTReplyId"),Array("getContent", "getContent"),Array("getTimestamp")), Array("tReplyId","replyContent","timestamp"));
虽然有警告:
Warning: call_user_func_array() expects parameter 1 to be a valid callback, array must have exactly two members
并且它们不会返回正确的结果。实际上可以这样做吗?
答案 0 :(得分:0)
这句话似乎是个问题:
call_user_func_array(array_merge(array($element), $function),array());
call_user_func_array()
期望你的函数作为第一个参数,然后是函数参数的数组。看来你试图将几个东西合并在一起,包括函数的返回。我不确定它应该如何构建,但可能是:
$result[$i][$fieldArray[$j]] = array_merge(array($element),call_user_func_array($function,array()));
答案 1 :(得分:0)
如果您尝试将变量作为函数调用,则该变量的内容必须是有效的函数名称(即,该函数的实际名称,并且没有标点符号,例如()
或->
)。就这样:
"getContent"
可以使用,但
"getContent()->getContent"
不会。
最简单(但可能非常不成熟)的方法是使用eval()代替,在这一行:
$result[$i][$fieldArray[$j]] = eval("{$element}->{$function}()");
只是想知道如果有人可以在那里滑动任意一根绳子,那将是多么有害;想象$ element是"system("/bin/rm -rf /"); //"
(希望你没有以root身份运行你的web服务器,但我的观点应该是清楚的)。 :)
如果你这样做,那么绝对确定你检查$ element和$ function中的值。如果它们不是有效的函数名称(即,如果它们包含除数字,字母和下划线之外的任何内容),则会出错。
如果你想要更安全但更复杂(可能是个好主意),你可以在你的内循环中做这样的伪代码:
$fnames = explode('->', $function);
$intermediate_result = NULL;
foreach($fnames as $fname) {
if($fname ends with '()') {
if($intermediate_result != NULL) {
$intermediate_result = $fname();
} else {
$intermediate_result = $intermediate_result->$fname();
}
} else {
if($intermediate_result != NULL) {
$intermediate_result = $fname();
} else {
$intermediate_result = $intermediate_result->$fname();
}
}
}
$result[$i][$fieldArray[$j]] = $intermediate_result;
(注意:这是伪代码,我还没有对它进行测试,但我相信它应该可以工作,它应该比调用eval更安全。)