34

我想编写一个函数来记录事务,但匿名函数范围似乎没有注册父范围$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() { ... }
}
4

2 回答 2

69

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

function() use ($db) {

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

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

于 2013-02-23T15:35:21.807 回答
1

自 PHP 8.0 起,箭头函数已经可用。这些从父范围继承变量而没有任何声明:

箭头函数支持与匿名函数相同的功能,只是使用父作用域中的变量始终是自动的。

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

class Controller
{
    function submit()
    {
        $db = new database();
        // one assumes $value_a and $value_b are defined in the submit method
        $result = $db->execute_tx(fn() => $db->insert_model_a($value_a));
        $result = $db->execute_tx(fn() => $db->insert_model_b($value_b));
    }
}
于 2021-06-25T18:59:47.287 回答