PHP 5.4 - '关闭$ this support'

时间:2011-04-20 17:06:50

标签: php closures

我看到PHP 5.4的新计划功能是:特征,数组解除引用,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;
                     }
                 };

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

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

4 个答案:

答案 0 :(得分:74)

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

  

对于PHP 5.3 $,这种对闭包的支持被删除了,因为无法达成共识如何以理智的方式实现它。此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

并且具有历史意义:

答案 1 :(得分: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

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

答案 2 :(得分:22)

在@ 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

答案 3 :(得分:2)

仅仅基于其他答案,我认为这个例子将演示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