在PHP 5.3.0中,“use”标识符的功能是什么?

我正在检查一些PHP 5.3.0功能,并且在网站上运行了一些看起来很有趣的代码:

public function getTotal($tax)
{
    $total = 0.00;

    $callback =
        /* This line here: */
        function ($quantity, $product) use ($tax, &$total)
        {
            $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                strtoupper($product));
            $total += ($pricePerItem * $quantity) * ($tax + 1.0);
        };

    array_walk($this->products, $callback);
    return round($total, 2);
}

作为匿名函数的例子之一。

有人知道吗? 任何文档? 它看起来很邪恶,是否应该使用它?


这就是PHP如何表达闭包。 这根本不是邪恶的,事实上它非常强大和有用。

基本上这意味着你允许匿名函数“捕获”它之外的局部变量(在这种情况下, $tax和一个对$total的引用)并且保留它们的值(或者在$total参考的情况下到$total本身)作为匿名函数本身的状态。


一个更简单的答案。

function ($quantity) use ($tax, &$total) { .. };

  • 闭包是分配给变量的函数,所以你可以传递它
  • 闭包是一个独立的命名空间,通常情况下,你不能访问在这个命名空间之外定义的变量。 有关键字use
  • 使用允许您访问(使用)闭包中的后续变量。
  • 使用是早期绑定。 这意味着变量值在定义闭包时被复制。 因此,在闭包内修改$tax是没有外部影响的,除非它是一个指针,就像对象一样。
  • 您可以像&$total一样传递变量作为指针。 这样,修改$total的值会产生外部影响,原始变量的值会发生变化。
  • 闭包内部定义的变量无法从闭包外部访问。
  • 关闭和功能具有相同的速度。 是的,你可以在脚本中使用它们。
  • 正如@Mytskine指出的,最好的深入解释是闭包的RFC。 (Upvote他为此。)


    封闭是美丽的! 他们解决了许多匿名函数带来的问题,并且使得优雅的代码成为可能(至少只要我们谈论php)。

    JavaScript程序员一直使用闭包,有时甚至不知道它,因为绑定变量没有明确定义 - 这就是php中的“使用”。

    有比上述更好的现实世界的例子。 可以说你必须通过一个子值对多维数组进行排序,但是关键的变化。

    <?php
        function generateComparisonFunctionForKey($key) {
            return function ($left, $right) use ($key) {
                if ($left[$key] == $right[$key])
                    return 0;
                else
                    return ($left[$key] < $right[$key]) ? -1 : 1;
            };
        }
    
        $myArray = array(
            array('name' => 'Alex', 'age' => 70),
            array('name' => 'Enrico', 'age' => 25)
        );
    
        $sortByName = generateComparisonFunctionForKey('name');
        $sortByAge  = generateComparisonFunctionForKey('age');
    
        usort($myArray, $sortByName);
    
        usort($myArray, $sortByAge);
    ?>
    

    警告:未经测试的代码(我没有安装atm的php5.3),但应该看起来像这样。

    有一个缺点:如果你用闭包来对付它们,很多PHP开发者可能会有点无奈。

    为了更好地理解闭包的好处,我会给你另一个例子 - 这次用javascript。 其中一个问题是范围和浏览器固有的异步性。 特别是,如果涉及到window.setTimeout(); (或间隔)。 所以,你传递一个函数setTimeout,但你不能给任何参数,因为提供参数执行代码!

    function getFunctionTextInASecond(value) {
        return function () {
            document.getElementsByName('body')[0].innerHTML = value; // "value" is the bound variable!
        }
    }
    
    var textToDisplay = prompt('text to show in a second', 'foo bar');
    
    // this returns a function that sets the bodys innerHTML to the prompted value
    var myFunction = getFunctionTextInASecond(textToDisplay);
    
    window.setTimeout(myFunction, 1000);
    

    myFunction返回一个带有一种预定义参数的函数!

    说实话,自5.3以来,我更喜欢php以及匿名函数/闭包。 命名空间可能更重要,但它们性感不那么好。

    链接地址: http://www.djcxy.com/p/59139.html

    上一篇: In PHP 5.3.0, what is the function "use" identifier?

    下一篇: Advanced Search Using Hibernate Search