我想编写一个函数来执行一些记录事务的脏工作,但是匿名函数范围似乎没有注册父范围$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() { ... }
}
答案 0 :(得分:56)
使用use
关键字将变量绑定到函数的范围。
function() use ($db) {
闭包还可以从父作用域继承变量。必须在函数头[using
use
]中声明任何此类变量。
答案 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));
}
}