从匿名PHP函数中的父作用域访问变量

时间:2013-02-23 15:33:41

标签: php closures

我想编写一个函数来执行一些记录事务的脏工作,但是匿名函数范围似乎没有注册父范围$db$value变量。如何将变量传递给闭包?

具有讽刺意味的是,SO标签'闭包'并没有非常准确地描述它的PHP版本......?

class controller
{
    function submit()
    {
        $db = new database();
        $result = $db->execute_tx(function() {
            $db->insert_model_a($value_a); // ERROR: $db is non-object
            $db->insert_model_b($value_b);
        });
    }
}

class database
{
   function execute_tx($atomic_action)
   {
        try
        { 
            $this->start();
            $atomic_action();
            $this->commit();
            // etc..
        }
        catch(...)
        { 
            $this->rollback();
            // etc..
        } 
        finally
        {
            // etc..
        }
   }

   function insert_model_a() { ... }
   function insert_model_b() { ... }
}

2 个答案:

答案 0 :(得分:56)

使用use关键字将变量绑定到函数的范围。

function() use ($db) {
  

闭包还可以从父作用域继承变量。必须在函数头[using use]中声明任何此类变量。

     

http://www.php.net/manual/en/functions.anonymous.php

答案 1 :(得分:1)

自 PHP 8.0 起,arrow functions 已可用。这些从父作用域继承变量,没有任何声明:

<块引用>

箭头函数支持与 anonymous functions 相同的功能,除了使用父作用域中的变量始终是自动的。

它们旨在与单个表达式一起使用,因此对于问题中的代码并不理想,但使用其中两个可以:

class Controller
{
    function submit()
    {
        $db = new database();
        $result = $db->execute_tx(fn() => $db->insert_model_a($value_a));
        $result = $db->execute_tx(fn() => $db->insert_model_b($value_b));
    }
}