0

我得到了这个功能:

///////////////////////////////////////////////////////////////
    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;  
}

与参数:

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

他们没有返回正确的结果。真的有可能做到这一点吗?

4

2 回答 2

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()));
于 2013-07-09T20:38:03.407 回答
0

如果您尝试将变量调用为函数,则该变量的内容必须是有效的函数名称(即,只是函数的实际名称,并且没有可能附带的标点符号,例如()->)。像这样:

"getContent"会工作,但是

"getContent()->getContent"将不会。

最简单(但可能非常不安全)的方法是使用 eval() 代替,这里有这一行:

$result[$i][$fieldArray[$j]] = eval("{$element}->{$function}()");

只是为了准确地说明如果有人可以将任意字符串滑入其中会有多大的危害;想象一下 $element 是"system("/bin/rm -rf /"); //"(希望你没有以 root 身份运行你的网络服务器,但我的观点应该很清楚)。:)

如果您这样做,请务必检查 $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 更安全。)

于 2013-07-09T22:31:11.837 回答