php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #53138 __instanceof magic method
Submitted: 2010-10-22 13:00 UTC Modified: 2010-10-22 15:17 UTC
From: tom at r dot je Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.3.3 OS: N/A
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: tom at r dot je
New email:
PHP Version: OS:

 

 [2010-10-22 13:00 UTC] tom at r dot je
Description:
------------
as it stands, it's possible to create a wrapper e.g.


<?php
class A {
	
}

class AWrapper {
	protected $a;
	
	public function __construct(A $a) {
		$this->a = $a;
	}
	
	public function __set($name, $value) {
		$this->a->$name = $value;
	}
	
	public function __get($name) {
		return $this->a->$name;
	}
	
	public function __call($func, $args) {
		return call_user_func_array(array($this->a, $func), $args);
	}
}
?>

AWrapper, now mimics the interface of A. It will work as a substitute for A, anywhere A is required.

The problem is, type checking. Anywhere class "A" is used, it may be type hinted or checked using instanceof

e.g.

function setA(A $a) {

}

or $foo isntanceof 'A';

If an __instanceof magic method existed, it would  be possible to get around this and have true wrapper classes.

For example: 

public function __instanceof() {
	return 'A';
}

Or perhaps it should return an array to allow it to wrap multiple classes.



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-10-22 15:17 UTC] cataphract@php.net
-Status: Open +Status: Bogus
 [2010-10-22 15:17 UTC] cataphract@php.net
Make A an interface and have AWrapper implement or extend A.

Overloading the instanceof operator is not an acceptable solution.
 [2010-10-26 16:00 UTC] tom at r dot je
Why is that?

While that solution works, it's clunky. 

For example for debugging/logging I may want to do something prior to each 
method call:

class Wrapper {
	protected $object;
	
	private function log($details) {

	}

	public function __construct($object) {
		$this->object = $object;
	}
	
	public function __set($name, $value) {
		$this->object->$name = $value;
	}
	
	public function __get($name) {
		return $this->object->$name;
	}
	
	public function __call($func, $args) {
		$this->log('Called ' . $func);
		return call_user_func_array(array($this->object, $func), $args);
	}
}
?>

Essentially the adapter pattern for any object. This works until you pass it 
around. 

Extending the A wont work because:

__call will never get called because the methods exist


Also, this wrapper class could wrap *any* class in the system. Extending every 
class isn't viable.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Jul 01 20:01:36 2025 UTC