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()関数が最初のパラメーターとして期待され、次に関数引数の配列が2番目に期待されます。関数の戻りを含め、いくつかのものを一緒にマージしようとしているようです。どのように構造化されているかはわかりませんが、おそらく次のようになります。

$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 /"); //"てください (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 を呼び出すよりも安全であるはずです。)

于 2013-07-09T22:31:11.837 に答える