PHP:如何将实例变量传递给闭包?

Posted

技术标签:

【中文标题】PHP:如何将实例变量传递给闭包?【英文标题】:PHP: How to pass instance variable to closure? 【发布时间】:2014-07-12 05:52:33 【问题描述】:

如果你想在一个类中使用闭包,你如何从那个类中传入一个实例变量?

class Example 
    private $myVar;
    public function test() 
        $this->myVar = 5;
        $func = function() use ($this->myVar)  echo 'myVar is: ' . $this->myVar; ;

        // The next line is for example purposes only if you want to run this code.
        // $func is actually passed as a callback to a library, so I don't have
        // control over the actual call.
        $func();
    

$e = new Example();
$e->test();

php 不喜欢这种语法:

PHP Fatal error:  Cannot use $this as lexical variable in example.php on line 5

如果你脱掉$this->那么它就找不到变量了:

PHP Notice:  Undefined variable: myVar in example.php on line 5

如果您按照某些地方的建议使用use (xxx as $blah),则无论您是否使用$this,语法似乎都是无效的:

PHP Parse error:  syntax error, unexpected 'as' (T_AS), expecting ',' or ')' in example.php on line 5

有没有办法做到这一点?我可以让它工作的唯一方法是使用一个狡猾的解决方法:

$x = $this->myVar;
... function() use ($x)  ...

【问题讨论】:

你最后的“解决方法”就是我会怎么做。 你为什么认为它很狡猾?正如它所说,您不能将$this 用作词法变量,因此您需要使用另一个变量。这就是$x 这很狡猾,因为它增加了额外的复制操作。我必须将变量复制到$x,然后将$x 第二次复制到闭包中。如果我可以做类似function () use ($this->myVar as $x) 这样的事情,那么它将避免额外的复制并使代码更整洁。 PHP 使用惰性复制,它最初只使用引用,仅在其中一个被修改时复制。 FWIW,PHP 5.4 支持 $this 内部闭包。 【参考方案1】:

为什么不呢?:

    $func = function($param) echo 'myVar is: ' . $param; ;
    $func($this->myVar);

更新

@Bramar 对。但是,如果只有 $myVar 是 public,它就会起作用。闭包没有关联的范围,因此它们不能访问私有成员和受保护成员。在您的特定情况下,您可以这样做:

    $this->myVar = 5;   
    $_var = $this->myVar;
    $func = function() use ($_var)  echo 'myVar is: ' . $_var; ;
    $func();

【讨论】:

对不起,$func() 仅用于示例目的。我确实将此函数作为回调传递给库,因此我无法控制函数的实际调用。【参考方案2】:

您可以使用您的解决方法。你也可以更笼统:

$self = $this;
$func = function() use ($self) 
    echo "myVar = " . $self->myVar;
;

在闭包中,您可以使用$self 而不是$this 访问任何公共属性或方法。

但它不适用于原始问题,因为有问题的变量是私有的。

【讨论】:

voodoo417 提出了一个很好的观点 - 这仅适用于公共变量,不适用于私有变量。 没想到。我已更新我的答案以反映此限制。【参考方案3】:

如果您使用的是 PHP 5.4 或更高版本,则可以直接在闭包内使用$this

$func = function() 
  echo 'myVar is: ' . $this->myVar;
;

【讨论】:

看起来this除了$this外还包含了parent::变量,用来访问对象$this的父类(如果有的话)。

以上是关于PHP:如何将实例变量传递给闭包?的主要内容,如果未能解决你的问题,请参考以下文章

PHP匿名函数闭包function use

浅析PHP中的闭包和匿名函数

将 JSON 编码的 PHP 变量传递给 HighCharts

将实例变量传递给装饰器

Terraform:如何将变量传递给 user_data 初始化脚本

如何将类实例传递给 LowLevelMouseProc?