0

次のようなコードを使用するライブラリがいくつかあります。

$args = array_merge(array(&$target, $context), $args);
$result = call_user_func_array($callback, $args);

どちらの場合もコードは異なりますが、私が示したコードは基本的に行われているものです。この $callback関数は次の署名を使用します。

function callback(&$target, $context);

どちらのライブラリもそれを文書化しており、サードパーティのコード(プラグインまたは拡張機能と呼びます)はその関数シグネチャを採用しています。つまり、どの拡張機能もコールバックをたとえばのように定義していません function my_extension_loader_callback($target, $context)

私を混乱させるのは、call_user_func_array()のドキュメントの次の文です。

PHP 5.4より前では、param_arr内の参照変数は、関数がそれぞれのパラメーターが参照によって渡されることを期待しているかどうかに関係なく、参照によって関数に渡されます。この形式の参照による呼び出し時間パスは非推奨の通知を発行しませんが、それでも非推奨であり、PHP5.4で削除されました。さらに、これは、関数のシグネチャが尊重される内部関数には適用されません。関数が参照によってパラメーターを予期しているときに値を渡すと、警告が発生し、がcall_user_func()返されFALSEます。

特に、強調表示された文は、PHPコードで定義された関数に対して行われていないことを示唆しているようです。

call_user_func_array()このように使用することはPHP5.4で機能しますか?

4

3 に答える 3

3

を使用するcall_user_func_array場合、新しいバージョンのPHPでは、関数が参照を予期しているときに値を渡すことはエラーと見なされます。

これは、PHP5.3.3より前の有効なPHPコードでした。

//first param is pass by reference:
my_function(&$strName){
}

//passing by value, not by reference, is now incorrect if passing by reference is expected:
call_user_func_array("my_function", array($strSomething));

//correct usage
call_user_func_array("my_function", array(&$strSomething));

上記の値渡しは警告なしでは不可能になりました(私のプロジェクトはあらゆる種類のエラー(通知、警告など)で例外をスローするように設定されています)ので、これを修正する必要がありました。

解決策 私はこの問題にぶつかり、これが私がそれを解決した方法です(私は小さなRPCサーバーを持っているので、パラメーターを逆シリアル化した後の参照値などはありません):

//generic utility function for this kind of situations
function &array_make_references(&$arrSomething)
{ 
    $arrAllValuesReferencesToOriginalValues=array();
    foreach($arrSomething as $mxKey=>&$mxValue)
        $arrAllValuesReferencesToOriginalValues[$mxKey]=&$mxValue;
    return $arrAllValuesReferencesToOriginalValues;
}

$strSomething参照によって渡されることはありませんが、それarray_make_references自体への参照になります。

call_user_func_array("my_function", array_make_references(array($strSomething)));

PHPの連中は、人々が誤って呼び出された関数(よく隠された落とし穴)を捕まえるのを助けることを考えていたと思いますcall_user_func_array

于 2012-07-01T13:26:39.673 に答える
1

call_user_func_array()返品の場合falseは問題があります。それ以外の場合はすべて問題ありません。

パラメータはデフォルトでは参照によって渡されなくなりましたが、明示的に渡されます。唯一の問題は、あなたの参照が中に失われることである可能性があります、array_merge()それをテストしていません。

于 2012-07-01T12:47:58.223 に答える
-1

PHP5.4にアップグレードするときにcall_user_func_array、参照によって渡される引数を使用するサイトが複数あるときに、これと同じ問題が見つかりました。

私が行った回避策は非常に単純で、call_user_func_arrayeval()を使用してそれ自体を完全な関数呼び出しに置き換えることで構成されています。これは最もエレガントなソリューションではありませんが、私にとっては目的に合っています:)

古いコードは次のとおりです。

call_user_func_array($target, &$arguments);

私が置き換えるもの:

$my_arguments = '';
for ($i=0; $i<count($arguments); $i++) {
    if ($i > 0) { $my_arguments.= ", "; }
    $my_arguments.= "\$arguments[$i]";
}
$evalthis = " $target ( $my_arguments );";
eval($evalthis);

お役に立てれば!

于 2014-07-05T20:00:16.690 に答える