首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 函數式程式設計:從字串呼叫到 Closure 完整演進

     編輯:PHP 相關知識

PHP 函數式特性的歷史演進與實作機制

函數即字串:PHP 早期的函數傳遞機制

PHP 無「函數型別」,函數名在非呼叫情境下會被解析為字串:

$func = 'strlen';  // 正確賦值方式
$func();           // 動態呼叫
call_user_func('strlen', 'test'); // 替代呼叫方式

此機制導致所有函數皆為全域,不支援重複定義,也無法像 JavaScript 那樣在執行期重新定義函數行為。

類別方法的動態呼叫

利用 PHP 的「變數變數」特性或 call_user_func() 陣列格式:

class Controller {
    public function login() { echo "Login"; }
}
$action = 'login';
$controller = new Controller();
$controller->$action();                    // 物件方法
Controller::$action();                     // 靜態方法
call_user_func(array('Controller', $action)); // 靜態方法回呼
call_user_func(array($controller, $action));  // 實例方法回呼

PHP 5.2.3+ 支援 'Class::method' 字串格式;PHP 5.3+ 引入命名空間後需加前綴:__NAMESPACE__ . '::Class::method'。

Lambda 與 Closure 的演進

PHP 5.3 前:create_function() 的侷限

$lambda = create_function('$a', 'return addslashes(trim($a));');
// 實際產生全域函數,名稱如 "\0lambda_1",無法真正捕獲外部變數

缺點:程式碼寫在字串中難維護、效能差、無法實作真正閉包。

PHP 5.3+:原生 Closure 支援

$data = range(0, 10);
$newData = array_map(function($v) {
    $a = range(0, $v);
    return array_sum($a);
}, $data);

// 真正的閉包:使用 use 關鍵字捕獲外部變數
function outer() {
    $a = 123;
    return function() use ($a) { echo $a; }; // 值捕獲(複製)
}
$inner = outer();
$inner(); // 輸出 123

閉包變數捕獲的陷阱與解決

function outer() {
    $a = 0;
    return function() use ($a) { return $a++; }; // 每次呼叫都輸出 0(值複製)
}
$inner = outer();
$inner(); // 0
$inner(); // 0

// 解決:引用捕獲
function outer() {
    $a = 0;
    return function() use (&$a) { return $a++; }; // 正確遞增
}
$inner = outer();
$inner(); // 0
$inner(); // 1
$inner(); // 2

函數式工具函數

PHP 內建 array_map、array_filter、array_reduce、array_walk 等高階函數,支援函數式資料處理風格:

array_walk($_REQUEST, 'trim'); // 對所有請求參數執行 trim
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved