call_user_func 和 call_user_func_array 是 PHP 的動態函數調用機制,允許以字符串/數組形式指定回調,運行時決定調用目標。二者功能相同,參數傳遞方式不同。
mixed call_user_func ( callable $callback, mixed ...$args ) mixed call_user_func_array ( callable $callback, array $param_arr )
function greet($name, $suffix = '!') { echo "Hello $name$suffix\n"; }
call_user_func('greet', 'World'); // Hello World!
call_user_func_array('greet', ['World', '!!']); // Hello World!!
class Utils {
public static function add($a, $b) { return $a + $b; }
}
echo call_user_func(['Utils', 'add'], 3, 5); // 8
echo call_user_func_array(['Utils', 'add'], [3, 5]); // 8
// PHP 5.3+ 支持類名字符串
$class = 'Utils';
call_user_func([$class, 'add'], 1, 2);
class Greeter {
public $prefix = 'Hi';
public function greet($name) { echo "$this->prefix, $name\n"; }
}
$obj = new Greeter();
call_user_func([$obj, 'greet'], 'Alice'); // Hi, Alice
call_user_func_array([$obj, 'greet'], ['Bob']); // Hi, Bob
$mul = function($a, $b) { return $a * $b; };
echo call_user_func($mul, 6, 7); // 42
二者均支持引用參數,效果等同直接調用:
function increment(&$n) { $n++; }
$a = 10;
call_user_func('increment', $a); // $a = 11
call_user_func_array('increment', [$a]); // $a = 12
// 陣列參數需顯式引用
call_user_func_array('increment', [&$a]); // $a = 13
| 場景 | 推薦 | 理由 |
|---|---|---|
| 固定/少量參數 | call_user_func | 代碼可讀性高,參數顯式 |
| 參數數量動態/不定 | call_user_func_array | 參數已在數組中,無需解包 |
| 中間件/攔截器模式 | call_user_func_array | 統一透傳 $args 數組 |
| 性能極度敏感 | 直接調用 | 動態調用有微小開銷(解析 callable、參數處理) |
$routes = [
'GET /user' => ['UserController', 'index'],
'POST /user' => ['UserController', 'store'],
];
[$class, $method] = $routes[$method . ' ' . $path] ?? ['ErrorController', '404'];
call_user_func([new $class, $method], $request);
$listeners = [
'user.registered' => [
['EmailService', 'sendWelcome'],
['StatsService', 'incrementUsers'],
]
];
foreach ($listeners[$event] as $listener) {
call_user_func_array($listener, [$user]);
}
class ServiceProxy {
private $instance;
public function __call($method, $args) {
if (!$this->instance) $this->instance = new RealService();
return call_user_func_array([$this->instance, $method], $args);
}
}
call_user_method 和 call_user_method_array 自 PHP 4.1 起棄用,PHP 7.0 移除,請勿使用。
callable 解析結果:$callback = [$obj, 'method']Closure::fromCallable() 創建閉包後調用略快call_user_func(_array) 是 PHP 動態編程的基石,支撐著框架路由、事件系統、插件架構等核心機制。掌握其四大調用模式、引用傳遞語義、與直接調用的性能權衡,能讓你靈活構建可擴展的系統架構。