PHP 5.4 - 'closure $this support'

I see that the new planned features for PHP 5.4 are: traits, array dereferencing, a JsonSerializable interface and something referred to as 'closure $this support'

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

While the others are either immediately clear (JsonSerialiable, array dereferencing) or i looked up the specifics (traits), I am not sure what 'closure $this support' is. I have been unsuccessful googling for it or finding anything about it on php.net

Does anyone know what this is supposed to be?

If i had to guess, it would mean something like this:

$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;
                     }
                 };

The significance (even if this example is trivial) being that in the past once the closure is constructed the bound 'use' variables are fixed. With 'closure $this support' they are more like members you can mess with.

Does this sound correct and/or close and/or reasonable? Does anyone know what this 'closure $this support' means?


This was already planned for PHP 5.3, but

For PHP 5.3 $this support for Closures was removed because no consensus could be reached how to implement it in a sane fashion. This RFC describes the possible roads that can be taken to implement it in the next PHP version.

It indeed means you can refer to the object instance (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

For a discussion, see the PHP Wiki

  • Closures: Object extension

and for historic interest:

  • closures (rfc)
  • removal-of-this (rfc:closures)

One thing that Gordon missed is re-binding of $this. While what he described is the default behaviour, it is possible to re-bind it.

Example

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

The closures bindTo instance method (alternatively use the static Closure::bind) will return a new closure with $this re-bound to the value given. The scope is set by passing the second argument, this will determine visibility of private and protected members, when accessed from within the closure.

  • PHP: Closure
  • Blog post: Closure Object Binding in PHP 5.4

Building on @Gordon's answer it is posible to mimic some hacky aspects of closure-$this in 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