將函數/可調用單元作為參數傳遞給另一個函數,在特定時機被調用。實現「控制反轉」、插件機制、事件驅動、策略模式。
function() {} (Closure)'strlen'['ClassName', 'method'][$obj, 'method']__invoke 的對象 $obj()fn() => ... (PHP 7.4+)is_callable()$cb = function() { echo 'hi'; };
var_dump(is_callable($cb)); // true
var_dump(is_callable('not_exist_func')); // false
call_user_func($callback, $arg1, ...)call_user_func_array($callback, $argsArray)$callback($arg1, ...) (PHP 5.4+ 推薦,性能更好)<?php
class EventDispatcher {
private $listeners = [];
public function on(string $event, callable $listener) {
$this->listeners[$event][] = $listener;
}
public function emit(string $event, $payload = null) {
foreach ($this->listeners[$event] ?? [] as $listener) {
$listener($payload);
}
}
}
// 使用
$dispatcher = new EventDispatcher();
// 訂閱
$dispatcher->on('order.created', function($order) {
echo "發送郵件通知: 訂單 {$order['id']}\n";
});
$dispatcher->on('order.created', function($order) {
echo "更新庫存: 扣減商品 {$order['product_id']}\n";
});
// 觸發
$dispatcher->emit('order.created', ['id' => 1001, 'product_id' => 20, 'amount' => 99.00]);
/* 輸出:
發送郵件通知: 訂單 1001
更新庫存: 扣減商品 20
*/
| 場景 | 回調角色 |
|---|---|
| 數組處理 | array_map/array_filter/array_reduce 回調 |
| 路由分發 | 路由匹配後調用控制器回調 |
| 中間件管道 | 每層中間件接收 $next 回調決定是否繼續 |
| 異步任務 | 任務完成/失敗回調 |
| 策略模式 | 不同算法封裝為回調,運行時注入 |
| 鉤子系統 | WordPress add_action/apply_filters 本質是回調註冊/觸發 |
Closure::bindTo()class A { private $secret = 42; }
$closure = function() { return $this->secret; };
$bound = Closure::bind($closure, new A(), 'A');
echo $bound(); // 42,閉包綁定到 A 實例作用域,可訪問私有屬性
function process(callable $handler, $data) {
return $handler($data);
}
// PHP 8.0+ 可用更精確的簽名(需反射或文檔約定)
// function process(Closure(string): int $handler, string $data): int
回調是 PHP 實現靈活擴展、解耦的核心機制。現代 PHP 推薦直接調用 $callback(...),配合 callable 類型提示與 is_callable 防禦性檢查,善用閉包捕獲上下文變量(use 關鍵字)實現狀態封裝。