關於PHP閉包和回調的思考

閉包

閉包函數也叫匿名函數,簡單地說就是沒有名稱的函數,經常作爲回調函數的參數。

簡單應用

<?php
	$test = function($a){
		echo pow(2,$a);
	};
	$test(3); //print -- 8

use關鍵字

use關鍵字在閉包函數中的角色是讓閉包函數使用非傳參的變量,即讓閉包函數有能力捕獲外界變量。

<?php
	$b = 3;
	$test = function($a) use($b){
		echo $a+$b;
	};
	$test(4); //print -- 7

注意: 閉包內所引用的變量不能被外部所訪問(即,內部對變量的修改,外部不受影響),若想要在閉包內對變量的改變從而影響到上下文變量的值,需要使用&的引用傳參。

<?php
	$b = 3;
	$test = function() use(&$b){
		$b=9;
	};
	echo $b; //print -- 9

PHP的閉包類(Closure)

其實在PHP中定義一個閉包函數其實就是一個Closure類的實例;

<?php
	
	$test = function($a) {
		echo $a;
	};
	var_dump($test);
	/*print --
	object(Closure)#2 (1) {
  		["parameter"]=>
  			array(1) {
    			["$a"]=>
    			string(10) "<required>"
  			}
	}*/

另外,Closure可以將其他類的實例綁定到Closure的實例中,進而操作其他類的私有變量等。

<?php
class Test
{
	private $a = 1;
}
$test = new Test();
var_dump($test);
/*print --
object(Test)#2 (1) {
  ["a":"Test":private] => int(1)
}
*/
$func=Closure::bind(function () use ($test) {
    $test->a = 8;

}, $test, test::class);
var_dump($func);
/*print --
object(Closure)#5 (2) {
  ["static"]=>
  array(1) {
    ["test"]=>
    object(Test)#2 (1) {
      ["a":"Test":private]=>
      int(1)
    }
  }
}
*/
call_user_func($func);//執行閉包函數$func
var_dump($test);
//** 可以看到私有變量a的值被修改,1->8 **
/*print --
object(Test)#2 (1) {
  ["a":"Test":private]=>
  int(8)
}
*/

回調

回調函數其實就是將一個函數作爲另一個函數的參數,這樣在一些場景下可以達到一些特定作用,其實回調在異步(js)中特別有用,用於捕獲異步結果。
PHP自帶很多回調函數:

call_user_func()call_user_func_array()//一些數組函數
array_reduce();
array_walk();

我們也可以自己寫回調函數,這樣的形式在js中用的多,php並不多:

<?php
function a($a)
{
	if($a>100){
		return true;
	}
	return false;
}

function test($a,$b)
{
	if($a($b)){
		echo $b;
	}else{
		echo 50;
	}
}
test('a',500);//print -- 500
test('a',20);//print -- 50

參考

php Closure官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章