PHP: Extending stdClass with Closures (plus Visitor)

From the red-wine department: $this remains unresolved so of limited use, but some fun anyway:

class Extendable {
	static function import($context) {
		$self = new static();
		while (is_callable($context)) $context = $context($self);
		if (is_array($context) || is_object($context) || is_a($context, 'Traversable')) {
			foreach($context as $key => $value)
				$self->$key = &$value; # preserve keys if
		return $self;
	public function __call($name, $args) {
		if (isset($this->$name) && is_callable($this->$name)) {
			return call_user_func_array($this->$name, $args);
		throw new BadFunctionCallException(sprintf('Undefined function %s.', $name));

class Visitor extends Extendable {
	private $host;
	public function __construct($host) {
		$this->host = $host;
	public function __get($member) {
		if (in_array($member, get_object_vars($this->host), true)) {
			return $this->host->$member;
		throw new InvalidArgumentException(sprintf('Undefined variable "%s".', $member));
	public function __call($name, $args) {
		$host = $this->host;
		if (in_array($name, get_class_methods(get_class($host))))
			return call_user_func_array(array($host, $name), $args);
		if (isset($host->$name) && is_callable($host->$name))
			return call_user_func_array($host->$name, $args);
		parent::__call($name, $args);

// extenable example:

$test = new Extendable();

$test->test = function($text) {echo $text;};


$seco = Extendable::import( array('test' => function($text) {echo $text;}) );


$thir = Extendable::import($seco);


$thir->test = function() { echo 'new'; };


// visitor example:

class Test {
	private $tag = '1-2-3-TEST';
	function dump() {
	function __toString() {
		return $this->tag;

$test = new Test();

echo (string) $test, '<hr>';

$test = new Visitor($test);

$test->test = function() {echo 'Test Called.';};




And before you ask: It’s just that I was wondering the following did not work:

$test = new StdClass;

$test->test = function($test) { echo $test; };

$test->test('abc'); // fatal error

// or //

$test2 = (object) array( 'test' => function($test) {echo $test;} ));

$test2->test('def'); // fatal error
This entry was posted in PHP Development, Pressed and tagged , . Bookmark the permalink.

1 Response to PHP: Extending stdClass with Closures (plus Visitor)

  1. pe says:

    closures are reallly cool, no more create_functions.
    And since stdClass is not a “PHP base class”, implements no interceptors and interfaces, theres no magic, we shouldn’t use it 😉

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.