匿名函數(Anonymous functions),也叫閉包函數(closures),允許 臨時建立一個沒有指定名稱的函數。最經常用作回呼函數(callback)參數的值。當然,也有其它應用的情況。
Example #1 匿名函數樣本
<?phpecho preg_replace_callback ( '~-([a-z])~' , function ( $match ) { return strtoupper ( $match [ 1 ]);}, 'hello-world' );// 輸出 helloWorld?>
閉包函數也可以作為變數的值來使用。PHP 會自動把此種運算式轉換成內建類 Closure 的對象執行個體。把一個 closure 對象賦值給一個變數的方式與普通變數賦值的文法是一樣的,最後也要加上分號:
Example #2 匿名函數變數賦值樣本
<?php$greet = function( $name ){ printf ( "Hello %s\r\n" , $name );};$greet ( 'World' );$greet ( 'PHP' );?>
閉包可以從父範圍中繼承變數。 任何此類變數都應該用 use 語言結構傳遞進去。
Example #3 從父範圍繼承變數
<?php$message = 'hello' ;// 沒有 "use"$example = function () { var_dump ( $message );};echo $example ();// 繼承 $message$example = function () use ( $message ) { var_dump ( $message );};echo $example ();// Inherited variable's value is from when the function// is defined, not when called$message = 'world' ;echo $example ();// Reset message$message = 'hello' ;// Inherit by-reference$example = function () use (& $message ) { var_dump ( $message );};echo $example ();// The changed value in the parent scope// is reflected inside the function call$message = 'world' ;echo $example ();// Closures can also accept regular arguments$example = function ( $arg ) use ( $message ) { var_dump ( $arg . ' ' . $message );};$example ( "hello" );?>
以上常式的輸出類似於:
Notice: Undefined variable: message in /example.php on line 6NULLstring(5) "hello"string(5) "hello"string(5) "hello"string(5) "world"string(11) "hello world"
這些變數都必須在函數或類的頭部聲明。 從父範圍中繼承變數與使用全域變數是不同的。全域變數存在於一個全域的範圍,無論當前在執行的是哪個函數。而 閉包的父範圍是定義該閉包的函數(不一定是調用它的函數)。樣本如下:
Example #4 Closures 和範圍
<?php// 一個基本的購物車,包括一些已經添加的商品和每種商品的數量。// 其中有一個方法用來計算購物車中所有商品的總價格,該方法使// 用了一個 closure 作為回呼函數。class Cart{ const PRICE_BUTTER = 1.00 ; const PRICE_MILK = 3.00 ; const PRICE_EGGS = 6.95 ; protected $products = array(); public function add ( $product , $quantity ) { $this -> products [ $product ] = $quantity ; } public function getQuantity ( $product ) { return isset( $this -> products [ $product ]) ? $this -> products [ $product ] : FALSE ; } public function getTotal ( $tax ) { $total = 0.00 ; $callback = function ( $quantity , $product ) use ( $tax , & $total ) { $pricePerItem = constant ( CLASS . "::PRICE_" . strtoupper ( $product )); $total += ( $pricePerItem * $quantity ) * ( $tax + 1.0 ); }; array_walk ( $this -> products , $callback ); return round ( $total , 2 );; }}$my_cart = new Cart ;// 往購物車裡添加條目$my_cart -> add ( 'butter' , 1 );$my_cart -> add ( 'milk' , 3 );$my_cart -> add ( 'eggs' , 6 );// 打出出總價格,其中有 5% 的銷售稅.print $my_cart -> getTotal ( 0.05 ) . "\n" ;// 最後結果是 54.29?>
匿名函數目前是通過 Closure 類來實現的。
版本 說明
5.4.0 $this 可用於匿名函數。
5.3.0 可以使用匿名函數。