在匿名 PHP 函数中从父范围访问变量

Posted

技术标签:

【中文标题】在匿名 PHP 函数中从父范围访问变量【英文标题】:Access variables from parent scope in anonymous PHP function 【发布时间】:2013-02-09 03:13:33 【问题描述】:

我想编写一个函数来记录事务,但匿名函数作用域似乎没有注册父作用域$db$value 变量。如何将变量传递到闭包中?

具有讽刺意味的是,SO 标签“closures”并没有非常准确地描述它的 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()  ... 

【问题讨论】:

【参考方案1】:

使用use 关键字将变量绑定到函数的作用域中。

function() use ($db) 

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

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

【讨论】:

这是唯一的方法吗?因为我在一些提交中有 10 到 15 个值,而且我有很多提交要通过... 是的。您必须显式导入您希望闭包关闭的变量。 @Jake 如果您在该函数中有 10-15 个值的状态,那么您做错了。 @Jack 为什么会这样?为什么这么肯定? 这刚刚结束了 45 分钟的挫败感。太棒了。【参考方案2】:

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

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

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

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));
    

【讨论】:

以上是关于在匿名 PHP 函数中从父范围访问变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 1.5 中从父控制器访问组件方法

如何在 swift 中从父视图访问容器视图子视图

从匿名函数汇编脚本访问全局变量

在 PyQt 的子窗口中从父窗口访问数据

如何在颤动中从父小部件访问所有孩子的状态?

PHP疑难杂症