PHP 5.4 - '关闭$ this support'

jon*_*tar 68 php closures

我看到PHP 5.4的新计划功能是:traits,array dereferencing,JsonSerializable接口和称为' closure $this support'的东西

http://en.wikipedia.org/wiki/Php#Release_history

虽然其他人要么立即清楚(JsonSerialiable,阵列解除引用),要么我查找具体(特征),我不确定'封闭$这个支持'是什么.我在谷歌搜索它或在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;
                     }
                 };
Run Code Online (Sandbox Code Playgroud)

重要性(即使这个例子是微不足道的)是在过去一旦构造了闭包,绑定的"使用"变量是固定的.通过'关闭$ this support',他们更像是你可以搞砸的成员.

这听起来是否正确和/或接近和/或合理?有谁知道这个'封闭$这个支持'是什么意思?

Gor*_*don 74

这已经计划用于PHP 5.3,但是

对于PHP 5.3 $,这种对闭包的支持被删除了,因为无法达成共识如何以理智的方式实现它.此RFC描述了在下一个PHP版本中可以实现它的可能道路.

它确实意味着你可以引用对象实例(现场演示)

<?php
class A {
  private $value = 1;
  public function getClosure() 
  {
    return function() { return $this->value; };
  }
}

$a = new A;
$fn = $a->getClosure();
echo $fn(); // 1
Run Code Online (Sandbox Code Playgroud)

有关讨论,请参阅PHP Wiki

并为了历史兴趣:

  • @jon不,使用`use`是不可能的.到目前为止,您不能在任何PHP版本中使用$ this作为词法变量.我更新了Wiki中的示例以及指向显示当前PHP主干结果的键盘的链接. (3认同)

igo*_*orw 53

戈登遗漏的一件事是重新绑定$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
Run Code Online (Sandbox Code Playgroud)

闭包bindTo实例方法(或者使用静态Closure::bind)将返回一个新的闭包,并$this重新绑定给定的值.通过传递第二个参数来设置范围,这将确定从闭包内访问私有成员和受保护成员的可见性.

  • 用于描述`bindTo()`功能的+1,这是一个非常重要的功能. (6认同)

Xeo*_*oss 22

在@ Gordon的回答的基础上,它可以模仿关闭的一些hacky方面 - 在PHP 5.3中这个.

<?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
Run Code Online (Sandbox Code Playgroud)

  • 是的,但一个显着的区别是你不能从闭包内的`$ self`访问任何私有或受保护的属性或方法. (10认同)
  • +1哈哈,一年后找到了这个答案,它解决了我的问题.;) (3认同)
  • @Shiro,是的.5.3的此解决方法仅适用于公共属性. (2认同)