PHP 5.4 - '关闭 $this 支持'
Posted
技术标签:
【中文标题】PHP 5.4 - \'关闭 $this 支持\'【英文标题】:PHP 5.4 - 'closure $this support'PHP 5.4 - '关闭 $this 支持' 【发布时间】:2011-08-09 16:37:44 【问题描述】:我看到 php 5.4 的新计划功能是:特征、数组解引用、JsonSerializable 接口和称为“closure $this support
”的东西
http://en.wikipedia.org/wiki/Php#Release_history
虽然其他人要么立即清楚(JsonSeraliable,数组解引用),要么我查看了细节(特征),但我不确定“闭包 $this 支持”是什么。我在谷歌上搜索它或在 php.net 上找到任何关于它的东西都没有成功
有谁知道这应该是什么?
如果我不得不猜测,它的意思是这样的:
$a = 10; $b = 'strrrring';
//'old' way, PHP 5.3.x
$myClosure = function($x) use($a,$b)
if (strlen($x) <= $a) return $x;
else return $b;
;
//'new' way with closure $this for PHP 5.4
$myNewClosure = function($x) use($a as $lengthCap,$b as $alternative)
if(strlen($x) <= $this->lengthCap)) return $x;
else
$this->lengthCap++; //lengthcap is incremented for next time around
return $this->alternative;
;
意义(即使这个例子是微不足道的)是在过去,一旦构造了闭包,绑定的“使用”变量就固定了。有了“closure $this support”,他们更像是你可以搞砸的成员。
这听起来正确和/或接近和/或合理吗?有谁知道这个“关闭 $this 支持”是什么意思?
【问题讨论】:
FWIW,5.4 还不是 PHP 主干的官方名称——它在内部仍然被称为“5.3.99”,关于它是否真的会存在一些争议5.4 与否(与 6.0 相比,这将与大型 Unicode 重写“6.0”分支无关)。 啊,很高兴知道。感谢您修复标签 【参考方案1】:这已经为 PHP 5.3 计划好了,但是
对于 PHP 5.3 $this 对闭包的支持已被删除,因为无法就如何以理智的方式实现它达成共识。该 RFC 描述了在下一个 PHP 版本中实现它的可能途径。
这确实意味着你可以引用对象实例(live demo)
<?php
class A
private $value = 1;
public function getClosure()
return function() return $this->value; ;
$a = new A;
$fn = $a->getClosure();
echo $fn(); // 1
有关讨论,请参阅 PHP Wiki
Closures: Object extension为了历史利益:
closures (rfc) removal-of-this (rfc:closures)【讨论】:
哦,我走错了方向。你的意思是'$this' 是Foo
的实例,对吗?我认为 '$this' 是闭包本身。 use
还有必要吗?
@jon 不,使用use
甚至是不可能的。迄今为止,您不能在任何 PHP 版本中使用 $this 作为词法变量。我更新了 Wiki 中的示例和一个显示当前 PHP 主干结果的键盘链接。
谢谢,太好了。顺便说一句 - public $closure
没有做任何事情,只是分散了你的注意力,你在其他方面表现得很好
@Gordon - 我认为 jon 在一般情况下是指 use
- 不是特定于 $this
。 AFAIK,use
仍然需要访问局部变量。我期待着放弃use ($self)
把戏。 :)
@Bracketworks 我不能 100% 确定,但更多参与该决定的人告诉我,他们认为是 A。【参考方案2】:
Gordon 错过的一件事是重新绑定 $this
。虽然他描述的是默认行为,但可以重新绑定它。
示例
class A
public $foo = 'foo';
private $bar = 'bar';
public function getClosure()
return function ($prop)
return $this->$prop;
;
class B
public $foo = 'baz';
private $bar = 'bazinga';
$a = new A();
$f = $a->getClosure();
var_dump($f('foo')); // prints foo
var_dump($f('bar')); // works! prints bar
$b = new B();
$f2 = $f->bindTo($b);
var_dump($f2('foo')); // prints baz
var_dump($f2('bar')); // error
$f3 = $f->bindTo($b, $b);
var_dump($f3('bar')); // works! prints bazinga
闭包bindTo
实例方法(或者使用静态Closure::bind
)将返回一个新闭包,$this
重新绑定到给定的值。范围通过传递第二个参数来设置,这将确定从闭包内访问时私有成员和受保护成员的可见性。
【讨论】:
+1 用于描述bindTo()
功能,这是一个非常重要的功能。【参考方案3】:
基于@Gordon 的回答,可以在 PHP 5.3 中模仿闭包的一些 hacky 方面-$this。
<?php
class A
public $value = 12;
public function getClosure()
$self = $this;
return function() use($self)
return $self->value;
;
$a = new A;
$fn = $a->getClosure();
echo $fn(); // 12
【讨论】:
是的,但一个显着的区别是您不能从闭包内访问$self
上的任何私有或受保护的属性或方法。
+1 哈哈,一年后找到了这个答案,它解决了我的问题。 ;)
@jgivoni 你的意思是,在 PHP 5.3 中不能访问私有或受保护的变量?
@Shiro,是的。 5.3 的此解决方法仅适用于公共属性。
@Pacerier,我不知道在 PHP 5.3 的闭包中访问非公共属性的任何解决方法。最好的建议是升级到 5.4 或更高版本。【参考方案4】:
只是建立在其他答案的基础上,我认为这个例子将展示 PHP 5.4+ 的可能性:
<?php
class Mailer
public $publicVar = 'Goodbye ';
protected $protectedVar = 'Josie ';
private $privateVar = 'I love CORNFLAKES';
public function mail($t, $closure)
var_dump($t, $closure());
class SendsMail
public $publicVar = 'Hello ';
protected $protectedVar = 'Martin ';
private $privateVar = 'I love EGGS';
public function aMailingMethod()
$mailer = new Mailer();
$mailer->mail(
$this->publicVar . $this->protectedVar . $this->privateVar,
function()
return $this->publicVar . $this->protectedVar . $this->privateVar;
);
$sendsMail = new SendsMail();
$sendsMail->aMailingMethod();
// prints:
// string(24) "Hello Martin I love EGGS"
// string(24) "Hello Martin I love EGGS"
见:https://eval.in/private/3183e0949dd2db
【讨论】:
以上是关于PHP 5.4 - '关闭 $this 支持'的主要内容,如果未能解决你的问题,请参考以下文章
需要带有 PHP 5.4 版本的 XAMPP - windows [关闭]