ノード開発に詳しい人はコールバック関数に精通しているはずですが、PHP では一般的に使用されません。実際、PHP はコールバック関数もサポートしています。今日は、PHP でのコールバック関数と匿名関数の使用方法について詳しく説明します。
コールバック関数
コールバック関数: コールバック (つまり、call then back
は main 関数によって呼び出された後に main 関数に戻ります) は、関数パラメーターを通じて他のコードに渡される実行可能コードの特定のブロックへの参照を指します。 。
一般的な説明は、関数をパラメータとして別の関数に渡して使用するというものです。PHP には、array_map、usort、call_user_func_array など、「関数としてパラメータを必要とする」関数が多数あります。これらは、渡された関数を実行し、その後、結果を main 関数に直接返します。利点は、関数を値として使用するのが便利で、コードが簡潔で読みやすいことです。
匿名関数:
匿名関数は、名前が示すように、決まった関数名を持たない関数です。PHP では、匿名関数とクロージャを同じ概念として扱います (匿名関数は、PHP ではクロージャ関数とも呼ばれます)。もちろん、その使用法は変数としてのみ使用できます。
PHP で変数に関数を割り当てるには 4 つの方法があります:
私たちがよく使う方法: 関数は外部/または PHP の組み込みで定義され、関数名は文字列パラメーターとして直接渡されます。注: クラス静的関数の場合は、CLASS::FUNC_NAME として渡されます。
create_function($args, $func_code); を使用して関数を作成し、関数名を返します。
$func_code はコード本体、$args は ',' で区切られたパラメータ文字列です。
直接代入: $func_name = function($arg){statement};
匿名関数を直接使用し、関数を直接定義します。パラメーターは特定の変数値を割り当てません。最初のメソッドは一般的に使用されるため、これ以上言及しません。2 番目のメソッドも、eval() メソッドと同様に、PHP によって推奨されないものとして公式にリストされています。定義方法はあまりにも直感的ではないので、テスト以外の場所で使用したことはありません。ここでは、3 番目と 4 番目の使用法に焦点を当てます。
後の 2 つによって作成された関数は、匿名関数、つまりクロージャ関数と呼ばれます。3 番目の代入メソッドによって作成された関数は、非常に柔軟であり、変数を介して渡すことができます。 is_callable($func_name) を使用してこの関数を呼び出せるかどうかをテストすることも、$func_name($var) を通じて直接呼び出すこともできます。4 番目の方法で作成された関数は、JS のコールバック関数に似ていますが、変数の割り当てが必要です。
もう 1 つの特別な導入は、関数を定義するときに親スコープ内の変数を参照するために使用できる、 function($arg) use($outside_arg) {function_statement} です。 。このうち、$outside_arg は親スコープ内の変数であり、function_statement 内で使用できます。
この使い方は「パラメータ値の数を決定する」コールバック関数で使用されます。 たとえば、usort では $callback のパラメータ値が 2 つの項目である必要がありますが、並べ替えに影響を与えるために他のパラメータを導入する必要がある場合はどうすればよいでしょうか? use() キーワードを使用すると、内部使用のために新しい変数を $callback に導入するのに非常に便利です。
array_map/array_filter/array_walk:
これら 3 つの関数の実行ロジックは比較的似ており、次のコードに似ているため、これら 3 つの関数をまとめます:
$result = []; foreach($vars as $key=>$val){ $item = callback(); $result[] = $item; } return $result; array_walk($vars, $callback)
コールバックは次のようになります:
$callback = function(&$val, $key[, $arg]){ doSomething($val); }
array_walk実行が成功したかどうかをブール値で返します。参照シンボルを $value に追加すると、関数内の $value 値を変更して、$vars 配列を変更する効果を得ることができます。 $callback には 2 つのパラメータが必要なため、array_walk は strto lower/array_filter などの $callback を渡すことができません。同様の関数を実現したい場合は、次に説明する array_map() を使用できます。
array_walk_recursive($arr, $callback);
戻り値と実行メカニズムはarray_walkに似ています;
コールバックはarray_walkと同じですが、違いは、$valが配列の場合、関数が再帰的に処理することです。 $val 下向き; 必須 この場合、$val は配列の $key であり、無視されることに注意してください。
array_filter($vars, $callback, $flag);
その $callback は次のようになります:
$callback = function($var){ return true or false; }
array_filter は、$callback の実行時に false を返す項目を除外し、array_filter はフィルタリングが完了した後の配列を返します。
3 番目のパラメータ $flag はコールバック パラメータ $var の値を決定しますが、これは PHP の上位バージョンの機能である可能性があります。私の PHP5.5.3 ではそれをサポートしていません。デフォルトでは、配列内の各項目の値が渡されます。フラグが ARRAY_FILTER_USE_KEY の場合、配列内の各項目のキーが渡され、ARRAY_FILTER_USE_BOTH がキーと値に渡されます。
array_map($callback, &$var_as [,$var_bs...]);
その $callback は次のようになります。
$callback = function($var_a[, $var_b...]){ doSomething($var_a, $var_b); }
コールバックによって処理された $var_as の配列を返します (複数の配列がある場合は、元の配列が変更されます)。 2 つの配列の同じ順序の項目が処理に渡され、実行回数はパラメーター配列内の項目の最大数になります。
usort/array_reduce
callback = function($left, $right){ $res = compare($left, $right); return $res; }
$vars中的元素会被取出会被由小到大升序排序。 想实现降序排列,将$callback的返回值反一下就行了。
array_reduce($vars ,$callable [, mixed $initial = NULL])
$callback应该如下:
$callback = function($initial, $var){ $initial = calculate($initail, $var); return $initial; }
初始值$initial默认为null,返回经过迭代后的initial;一定要将$initial返回,这样才能不停地改变$initial的值,实现迭代的效果。
这里顺便说一下map和reduce的不同:
map:将数组中的成员遍历处理,每次返回处理后的一个值,最后结果值为所有处理后值组成的多项数组;
reduce:遍历数组成员,每次使用数组成员结合初始值处理,并将初始值返回,即使用上一次执行的结果,配合下一次的输入继续产生结果,结果值为一项;
call_user_func/call_user_func_array
call_user_func[_array]($callback, $param)
$callback形如:
$callback = function($param){ $result = statement(); return $result; }
返回值多种,具体看$callback。
可用此函数实现PHP的事件机制,其实并不高深,在判断条件达成,或程序执行到某一步后 call_user_func()就OK了。这个我在之前的博客中也有介绍到:搭建自己的PHP框架心得(二)
总结
其实以上$callback不用单独定义并使用变量引用,使用上面说过的第四种函数定义方式,直接在函数内定义,使用‘完全’匿名函数就行了。 如:
usort($records, function mySortFunc($arg) use ($order){ func_statement; });
是不是逼格满满呢?
相关阅读:
PHP匿名函数和use子句用法实例,匿名use子句实例_PHP教程
以上がPHPコールバック関数の解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。