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

PHP 閉包(Closure)與匿名函數深度解析:從語法到實戰模式

     編輯:PHP 相關知識

PHP 5.3 引入閉包(Closure),即匿名函數,極大豐富了函數式編程能力。本文系統講解閉包語法、use 綁定機制、經典應用場景(計數器、遞歸解耦、延遲綁定),並附帶 array_walk 等內建函數結合示例。

基礎語法與 use 關鍵字

$a = function() use($b) { /* ... */ };

use 將外部作用域變量「捕獲」到閉包內部。默認按值捕獲(複製),加 & 為引用捕獲。

值捕獲 vs 引用捕獲

<?php
$msg = "Hello, everyone";
$fun = function () use($msg) {
    print "msg is: $msg. <br />";
};
$msg = "Hello, everybody"; // 修改外部變量
$fun(); // 輸出: msg is: Hello, everyone. (值捕獲,創建時拷貝)

// 引用捕獲
$msg = "Hello";
$funRef = function () use(&$msg) { print $msg; };
$msg = "World";
$funRef(); // 輸出: World
?>

經典應用 1:獨立計數器生成器

利用閉包「攜帶」自由變量狀態:

<?php
function counter() {
    $counter = 1;
    return function() use(&$counter) { return $counter++; };
}
$c1 = counter(); $c2 = counter();
echo $c1(); // 1
echo $c1(); // 2
echo $c2(); // 1(獨立狀態)
?>

每次調用 counter() 創建新的 $counter 和閉包,兩者互不干擾。

經典應用 2:簡化 array_walk 回調

購物車計算總價,閉包捕獲 $tax 和 $total(引用):

<?php
class Cart {
    const PRICE_BUTTER = 1.00; const PRICE_MILK = 3.00; const PRICE_EGGS = 6.95;
    protected $products = [];
    public function add($product, $qty) { $this->products[$product] = $qty; }
    public function getTotal($tax) {
        $total = 0.00;
        $callback = function ($qty, $product) use ($tax, &$total) {
            $price = constant(__CLASS__ . '::PRICE_' . strtoupper($product));
            $total += ($price * $qty) * ($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); // 54.29
?>

避免了 foreach 並在回調中直接修改外部 $total。

經典應用 3:解耦遞歸函數

匿名函數需引用自身調用,必須用 use(&$fn):

<?php
$fib = function($n) use(&$fib) {
    if ($n == 0 || $n == 1) return 1;
    return $fib($n - 1) + $fib($n - 2);
};
echo $fib(5); // 8

// 通用模式
$recursive = function () use (&$recursive) { /* ... */ };
?>

若不加 &,$fib($n-1) 會找不到函數(定義時 $fib 尚未賦值完成)。

經典應用 4:延遲綁定

<?php
$result = 0;
$one = function() { var_dump($result); };           // 未捕獲,報錯 NULL
$two = function() use ($result) { var_dump($result); }; // 值捕獲,輸出 0
$three = function() use (&$result) { var_dump($result); }; // 引用捕獲,輸出 1
$result++;
$one(); $two(); $three();
?>

use(&$var) 實現「調用時賦值」,use($var) 為「定義時拷貝」。

總結

閉包是 PHP 函數式編程的基石,核心在於 use 的捕獲策略。掌握值/引用捕獲、延遲綁定、遞歸自引用,即可編寫優雅的回調、工廠函數、狀態封裝等模式。PHP 7.4+ 更引入箭頭函數 fn() => ... 自動按值捕獲外部變量,進一步簡化語法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved