ホームページ >バックエンド開発 >PHPチュートリアル >PHP コールバック関数と匿名関数の詳細な解釈
この記事では主にPHPコールバック関数と匿名関数を紹介し、PHPコールバック関数と匿名関数の具体的な関数、使用法、および関連する注意事項を例の形で分析します。必要な友人は参考にしてください
詳細は次のとおりです。
コールバック関数と匿名関数
コールバック関数とクロージャーは JS にとって馴染みのないものであり、JS ではそれらを使用してイベント メカニズムを完成させ、多くの複雑な操作を実行できます。 PHP では一般的には使用されません。今日は、PHP のコールバック関数と匿名関数について説明します。
コールバック関数
コールバック関数: コールバック (つまり、コールバックは、main 関数によって呼び出され操作された後、main 関数に戻ります) は、実行可能コードの特定の部分への参照を指します。関数パラメータを通じて他のコードに渡されます。
一般的な説明は、関数をパラメータとして別の関数に渡して使用するというものです。PHP には、array_map、usort、call_user_func_array など、「関数としてパラメータを必要とする」関数が多数あります。これらは、渡された関数を実行し、その後、結果を main 関数に直接返します。利点は、関数を値として使用するのが便利で、コードが簡潔で読みやすいことです。
匿名関数
匿名関数は、名前が示すように、関数名が決まっていない関数です。PHPでは、匿名関数とクロージャを同じ概念として扱います(匿名関数は、PHPではクロージャ関数とも呼ばれます)。もちろん、その使用法は変数としてのみ使用できます。
PHP で関数を変数に代入する方法は 4 つあります:
① 私たちがよく使う方法: 関数は PHP の外部/または組み込みで定義され、関数名は文字列パラメータとして直接渡されます。注: クラス静的関数の場合は、CLASS::FUNC_NAME
として渡す必要があります。 CLASS::FUNC_NAME
的方式传入。
② 使用create_function($args, $func_code);
创建函数,会返回一个函数名。 $func_code为代码体,$args为参数字符串,以','分隔;
③ 直接赋值:$func_name = function($arg){statement}
④ 直接使用匿名函数,在参数处直接定义函数,不赋给具体的变量值;
第一种方式因为是平常所用,不再多提;第二种类似eval()方法的用法,也被PHP官方列为不推荐使用的方式,而且其定义方式太不直观,我除了测试外,也没有在其他地方使用过,也略过不提。在这里重点说一下第三种和第四种用法;
后两种创建的函数就被称为匿名函数,也就是闭包函数, 第三种赋值法方式创建的函数非常灵活,可以通过变量引用。可以用 is_callable($func_name) 来测试此函数是否可以被调用, 也可以通过$func_name($var)来直接调用;而第四种方式创建的函数比较类似于JS中的回调函数,不需要变量赋值,直接使用;
另外要特别介绍的是 use 关键词,它可以在定义函数时,用来引用父作用域中的变量;用法为 function($arg) use($outside_arg) {function_statement} 。其中$outside_arg 为父作用域中的变量,可以在function_statement使用。
这种用法用在回调函数“参数值数量确定”的函数中。 如usort需求$callback的参数值为两项,可是我们需要引入别的参数来影响排序怎么办呢?使用use()关键词就很方便地把一个新的变量引入$callback内部使用了。
array_map/array_filter/array_walk:
把这三个函数放在一块是因为这三个函数在执行逻辑上比较类似,类似于下面的代码:
$result = []; foreach($vars as $key=>$val){ $item = callback(); $result[] = $item; } return $result; array_walk($vars, $callback)
其callback应如下:
$callback = function(&$val, $key[, $arg]){ doSomething($val); }
array_walk返回执行是否成功,是一个布尔值。对$value添加引用符号可以在函数内改变$value值,以达到改变$vars数组的效果。由于其$callback对参数数量要求为两项,array_walk不能传入strtolower/array_filter之类的$callback,若想实现类似功能,可以使用接下来要说的array_map()
create_function($args, $func_code);
を使用して関数を作成し、関数名を返します。 $func_code はコード本体、$args は「,」で区切られたパラメータ文字列です③ 直接代入: $func_name = function($arg){statement}
もう 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 つの関数をまとめます。$callback = function($var){ return true or false; }そのコールバックは次のようになります。
$callback = function($var_a[, $var_b...]){ doSomething($var_a, $var_b); }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($left, $right){ $res = compare($left, $right); return $res; }🎜🎜🎜array_filter は $callback の実行時に false を返す項目を除外し、array_filter は $callback の実行後に戻ります。配列のフィルタリングが完了しました。 🎜🎜 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($initial, $var){ $initial = calculate($initail, $var); return $initial; }🎜🎜
返回$var_as经过callback处理后的数组(会改变原数组);如果有多个数组的时候将两个数组同样顺序的项目传入处理,执行次数为参数数组中项目最多的个数;
usort/array_reduce
把这两个函数放在一块,因为他们的执行机制都有些特殊。
usort(&$vars, $callback)
$callback应该如下:
callback = function($left, $right){ $res = compare($left, $right); return $res; }
usort返回执行成功与否,bool值。用户自定义方法 比较$left 和 $right,其中$left和$right是$vars中的任意两项;
$left > $right时返回 正整数, $left < $right时返回 负整数, $left = $right时返回0;
$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中的array_map,array_walk以及匿名函数
以上がPHP コールバック関数と匿名関数の詳細な解釈の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。