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:如何将实例变量传递给闭包?的主要内容,如果未能解决你的问题,请参考以下文章
将 JSON 编码的 PHP 变量传递给 HighCharts