note 98384 modified in functions.anonymous by danbrown
| From: | danbrown@php.net | 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