【问题标题】:Accessing outside variable using anonymous function as params使用匿名函数作为参数访问外部变量
【发布时间】:2012-01-14 06:58:59
【问题描述】:

基本上我使用这个方便的函数来处理数据库行(密切关注 PDO 和/或其他东西)

function fetch($query,$func) {
    $query = mysql_query($query);   
    while($r = mysql_fetch_assoc($query)) {
        $func($r);
    }
}

有了这个功能,我可以简单地做到:

fetch("SELECT title FROM tbl", function($r){
   //> $r['title'] contains the title
});

假设现在我需要将所有 $r['title'] 连接到一个 var 中(这只是一个示例)。

我怎么能这样做?我在想这样的事情,但它不是很优雅:

$result = '';
fetch("SELECT title FROM tbl", function($r){
   global $result;
   $result .= $r['title'];
});

echo $result;

【问题讨论】:

    标签: php closures scope


    【解决方案1】:

    你必须使用use 作为described in docs

    闭包也可以从父作用域继承变量。任何此类 变量必须在函数头中声明。继承 来自父作用域的变量与使用全局变量不同 变量。全局变量存在于全局范围内,即 无论执行什么功能都一样。

    代码:

    $result = '';
    fetch("SELECT title FROM tbl", function($r) use (&$result) {
       $result .= $r['title'];
    });
    

    但要小心(取自上一个链接中的一个 cmets):

    use() 参数是早期绑定的——它们使用变量的值 声明 lambda 函数的点,而不是点 其中调用 lambda 函数(后期绑定)。

    【讨论】:

    • 不应该去掉全局减速吗?
    • +1 用于强调early binding。但是我猜在上面的示例中,当 use (&$result) 通过引用传递时,这并不重要?
    • @DimitryK 是的,这里使用引用来绕过默认行为(早期绑定)。
    • @machineaddict 基本的use 早期绑定-如果您是指后期绑定的解决方法-您可以通过引用通过use 传递变量-使用& => use (&$result) 和更改 $result 变量,然后再调用匿名函数(或其他调用它的函数)
    • 由于类实例总是通过引用传递,因此您不需要为它们使用 &。 (除非您完全覆盖实例)。
    【解决方案2】:

    重写 'fetch' 来只调用一次 $func 怎么样?

    function fetch($query,$func) {
        $query = mysql_query($query);   
        $retVal = array();
        while($r = mysql_fetch_assoc($query)) {
            $retVal[] = $r;
        }
        $func($retVal);
    }
    

    这样你会只调用一次 $func 并在获取后重新处理数组? 即使调用 200 次函数也不能确定性能。

    【讨论】:

    • 是的,你是对的。但是,如果您有兴趣在这里和那里获得几毫秒,您可以使用 mysql_fetch_row() 而不是 mysql_fetch_assoc() ......这非常难以处理,因为您必须知道您的列位置。通过这样做,您将 2000 个请求(每个请求 30 行)从 0.205 传递到 0.180。
    猜你喜欢
    • 2020-08-19
    • 1970-01-01
    • 2013-08-16
    • 2012-12-31
    • 2014-04-09
    • 1970-01-01
    相关资源
    最近更新 更多