PHP 5.3+ 支援匿名函數 (Closure),需指派給變數使用:
$func = function($param) { echo $param; };
$func('some string'); // 輸出: some string
早期 create_function() 需用字串寫邏輯,難維護,已棄用。
// 1. 函數內定義並呼叫
function printStr() {
$func = function($str) { echo $str; };
$func('some string');
}
// 2. 函數回傳閉包
function getPrintStrFunc() {
return function($str) { echo $str; };
}
$printStrFunc = getPrintStrFunc();
$printStrFunc('some string');
// 3. 閉包作為參數傳遞 (回調模式)
function callFunc($func) { $func('some string'); }
callFunc(function($str) { echo $str; }); // 直接內聯傳遞
預設匿名函數無法存取定義時的上下文變數,需用 use 宣告:
function getMoney() {
$rmb = 1;
$dollar = 6;
$func = function() use ($rmb) {
echo $rmb;
echo $dollar; // 錯誤:未在 use 中宣告
};
$func();
}
function getMoney() {
$rmb = 1;
// 值綁定:複製當時的值
$func = function() use ($rmb) {
echo $rmb; // 1
$rmb++; // 修改的是副本
};
$func();
echo $rmb; // 仍為 1
}
// 參考綁定:& 符號
function getMoneyRef() {
$rmb = 1;
$func = function() use (&$rmb) {
echo $rmb; // 1
$rmb++; // 修改原變數
};
$func();
echo $rmb; // 變為 2
}
function getMoneyFunc() {
$rmb = 1;
return function() use (&$rmb) {
echo $rmb++;
};
}
$getMoney = getMoneyFunc();
$getMoney(); // 1
$getMoney(); // 2
$getMoney(); // 3
// 外部無法直接存取 $rmb,形成「閉包」封裝
echo preg_replace_callback('~-([a-z])~', function($match) {
return strtoupper($match[1]);
}, 'hello-world'); // 輸出: helloWorld
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;
$callback = function($quantity, $product) use ($tax, &$total) {
$price = constant(__CLASS__ . "::PRICE_" . strtoupper($product));
$total += ($price * $quantity) * ($tax + 1.0);
};
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% 稅
use 預設為值綁定 (複製),加 & 為參考綁定