無名稱函數,指派給變數即可調用:
$cl = function($name) {
return sprintf('hello %s', $name);
};
echo $cl('fuck'); // 輸出: hello fuck
echo preg_replace_callback('~-([a-z])~', function($match) {
return strtoupper($match[1]);
}, 'hello-world'); // 輸出: helloWorld
$message = 'hello';
$example = function() use ($message) {
var_dump($message);
};
$example(); // 輸出: hello
$message = 'world';
$example(); // 仍輸出: hello (定義時綁定值)
/* 參考綁定 */
$message = 'hello';
$example = function() use (&$message) {
var_dump($message);
};
$example(); // hello
$message = 'world';
$example(); // world (參考綁定,隨外部變化)
$message = 'hello';
$example = function($data) use ($message) {
return "{$data},{$message}";
};
echo $example('world'); // world,hello
class Cart {
// 類別常數定義價格
const PRICE_BUTTER = 1.00;
const PRICE_MILK = 3.00;
const PRICE_EGGS = 6.95;
protected $products = [];
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.0;
// 閉包捕獲 $tax (值綁定) 與 $total (參考綁定)
$callback = function($quantity, $product) use ($tax, &$total) {
// 存取類別常數:constant(__CLASS__ . "::PRICE_" . strtoupper($product))
$price = constant(__CLASS__ . "::PRICE_" . strtoupper($product));
$total += ($price * $quantity) * ($tax + 1.0);
};
// array_walk 遍歷陣列,將鍵值作為參數傳給回調
array_walk($this->products, $callback);
return round($total, 2);
}
}
$cart = new Cart();
$cart->add('butter', 1);
$cart->add('milk', 3);
$cart->add('eggs', 6);
echo $cart->getTotal(0.05); // 含 5% 稅
constant() 動態取得常數值,配合 __CLASS__ 魔術常數array_walk() 回調函數簽名:function($value, $key),此處對應 ($quantity, $product)use ($tax, &$total):$tax 為值綁定 (稅率固定),$total 為參考綁定 (累加總額)| 特性 | 閉包 | 類別私有方法 |
|---|---|---|
| 狀態封裝 | 透過 use 參考綁定 | 透過 $this-> 屬性 |
| 可攜性 | 可作為參數傳遞、回傳 | 綁定於類別實例 |
| 語法簡潔度 | 內聯定義較簡潔 | 需額外定義方法 |
| 效能 | 略低 (閉包物件開銷) | 略高 |
array_map/walk/filter, preg_replace_callback, usort