在官方文件定義中,匿名函式(Anonymous functions),也叫閉包函式(closures),允許臨時建立一個沒有指定名稱的函式。最經常用作回撥函式(callback)引數的值。
在laravel應用中,也是使用非常頻繁的語法特性
例如在定義路由時,通過閉包的方法,定義路由組
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// // 使用 first 和 second 中介軟體
});
Route::get('user/profile', function () {
// // 使用 first 和 second 中介軟體
});
});
laravel的許多集合函式也通過閉包來實現,例如
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->filter(function ($value, $key) {
return $value > 2;
});
$filtered->all();
// [3, 4]
以下示例來自官方文件匿名函式
匿名函式目前是通過 Closure 類來實現的。
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
// 輸出 helloWorld
?>
閉包函式也可以作為變數的值來使用。PHP 會自動把此種表示式轉換成內建類 Closure 的物件例項。把一個 closure 物件賦值給一個變數的方式與普通變數賦值的語法是一樣的,最後也要加上分號:
<?php
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
$greet('World');//輸出Hello World
$greet('PHP');//輸出Hello PHP
?>
閉包可以從父作用域中繼承變數。 任何此類變數都應該用 use 語言結構傳遞進去。 PHP 7.1 起,不能傳入此類變數: superglobals、 $this 或者和引數重名。
<?php
$message = 'hello';
// 沒有 "use"
$example = function () {
var_dump($message);
};
echo $example();//Notice: Undefined variable: message in /example.php on line 6
//輸出NULL
// 繼承 $message
$example = function () use ($message) {
var_dump($message);
};
echo $example();
//輸出hello
// Inherited variable's value is from when the function
// is defined, not when called
$message = 'world';
echo $example();
//輸出hello
// Reset message
$message = 'hello';
// Inherit by-reference
$example = function () use (&$message) {
var_dump($message);
};
echo $example();
//輸出hello
// The changed value in the parent scope
// is reflected inside the function call
$message = 'world';
echo $example();
//輸出world
// Closures can also accept regular arguments
$example = function ($arg) use ($message) {
var_dump($arg . ' ' . $message);
};
$example("hello");
//輸出hello world
?>
Closure::bind
官方文件給出定義如下:
Closure::bind — 複製一個閉包,繫結指定的$this物件和類作用域。
我的理解如下:
可通過預定義一個閉包,在後續中,通過bind方法傳入類物件和作用域,使閉包成為類的方法,laravel的巨集指令就有使用到此方法,後續會做相應研究。
根據官方給出的案例
<?php
class A {
private static $sfoo = 1;
private $ifoo = 2;
}
$cl1 = static function() {
return A::$sfoo;
};
$cl2 = function() {
return $this->ifoo;
};
$bcl1 = Closure::bind($cl1, null, 'A');
$bcl2 = Closure::bind($cl2, new A(), 'A');
echo $bcl1(), "\n";//輸出1
echo $bcl2(), "\n";//輸出2
?>
Closure::bind( Closure $closure , object $newthis [, mixed $newscope = ‘static’)可傳入的引數三個引數中,其中$closure為匿名函式,主要討論後面兩個引數$newthis,$newscope為繫結指定的$this物件和類作用域。
在以上案例中,bind方法中$bcl1只傳入了類作用域,代表在$cl1閉包函式作用域中允許訪問類的靜態變數,但不能訪問類的變數和類的方法。
$bcl2傳入了類作用域和$this物件,代表在$cl2可以訪問類的所有變數和類的所有方法,此時可通過閉包完成對類方法的擴充套件。
本作品採用《CC 協議》,轉載必須註明作者和本文連結