PHP 5.4 - 'closure $this support'

前端 未结 4 1682
生来不讨喜
生来不讨喜 2020-11-29 01:03

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

相关标签:
4条回答
  • 2020-11-29 01:45

    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
    0 讨论(0)
  • 2020-11-29 01:51

    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)
    0 讨论(0)
  • 2020-11-29 01:57

    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
    
    0 讨论(0)
  • 2020-11-29 01:58

    Just building on the other answers here, I think this example will demonstrate what is possible 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"
    

    see: https://eval.in/private/3183e0949dd2db

    0 讨论(0)
提交回复
热议问题