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

PHP 閉包與匿名函數深度探索:use 關鍵字、引用綁定與實戰應用

     編輯:PHP 綜合知識

匿名函數基礎

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:連結外部變數

預設匿名函數無法存取定義時的上下文變數,需用 use 宣告:

function getMoney() {
    $rmb = 1;
    $dollar = 6;
    $func = function() use ($rmb) {
        echo $rmb;
        echo $dollar; // 錯誤:未在 use 中宣告
    };
    $func();
}

值綁定 vs 參考綁定

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,形成「閉包」封裝

實戰應用:preg_replace_callback

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 預設為值綁定 (複製),加 & 為參考綁定
  • 綁定發生在函數定義時,非呼叫時
  • 3. 閉包可封裝狀態,外部無法直接存取內部變數 4. PHP 閉包功能較 JS 弱,但配合類別已足夠應付大多數場景 5. 回調函數、事件監聽、延遲執行是主要應用領域
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved