note 98384 modified in functions.anonymous by danbrown

From: Date: Fri, 11 Jun 2010 18:10:39 +0000
Subject: note 98384 modified in functions.anonymous by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-170070@lists.php.net to get a copy of this message
$this is currently (PHP 5.3.2) not usable directly with closures. One can write: <?php $self = $this; function () use ($self) { ... } ?> but then the private/protected members of $this cannot be used inside the closure. This makes closures much less useful in OO code. Until this is fixed, one can cheat using reflection: <?php class FullAccessWrapper { protected $_self; protected $_refl; public function __construct($self) { $this->_self = $self; $this->_refl = new ReflectionObject($self); } public function __call($method, $args) { $mrefl = $this->_refl->getMethod($method); $mrefl->setAccessible(true); return $mrefl->invokeArgs($this->_self, $args); } public function __set($name, $value) { $prefl = $this->_refl->getProperty($name); $prefl->setAccessible(true); $prefl->setValue($this->_self, $value); } public function __get($name) { $prefl = $this->_refl->getProperty($name); $prefl->setAccessible(true); return $prefl->getValue($this->_self); } public function __isset($name) { $value = $this->__get($name); return isset($value); } } /** * Usage: * $self = giveAccess($this); * function() use ($self) { $self->privateMember... } */ function giveAccess($obj) { return new FullAccessWrapper($obj); } // Example: class Foo { private $x = 3; private function f() { return 15; } public function getClosureUsingPrivates() { $self = giveAccess($this); return function () use ($self) { return $self->x * $self->f(); }; } } $foo = new Foo(); $closure = $foo->getClosureUsingPrivates(); echo $closure() . "\n"; // Prints 45 as expected ?> --was-- $this is currently (PHP 5.3.2) not usable directly with closures. One can write: <?php $self = $this; function () use ($self) { ... } ?> but then the private/protected members of $this cannot be used inside the closure. This makes closures much less useful in OO code. Until this is fixed, one can cheat using reflection: <?php class FullAccessWrapper { protected $_self; protected $_refl; public function __construct($self) { $this->_self = $self; $this->_refl = new ReflectionObject($self); } public function __call($method, $args) { $mrefl = $this->_refl->getMethod($method); $mrefl->setAccessible(true); return $mrefl->invokeArgs($this->_self, $args); } public function __set($name, $value) { $prefl = $this->_refl->getProperty($name); $prefl->setAccessible(true); $prefl->setValue($this->_self, $value); } public function __get($name) { $prefl = $this->_refl->getProperty($name); $prefl->setAccessible(true); return $prefl->getValue($this->_self); } public function __isset($name) { $value = $this->__get($name); return isset($value); } } /** * Usage: * $self = giveAccess($this); * function() use ($self) { $self->privateMember... } */ function giveAccess($obj) { return new FullAccessWrapper($obj); } // Example: class Foo { private $x = 3; private function f() { return 15; } public function getClosureUsingPrivates() { $self = giveAccess($this); return function () use ($self) { return $self->x * $self->f(); }; } } $foo = new Foo(); $closure = $foo->getClosureUsingPrivates(); echo $closure() . "\n"; // Prints 45 as expected http://php.net/manual/en/functions.anonymous.php

« previous php.notes (#170070) next »