Catégories
Geek Hacking

friend class in PHP

SO, I wanted to use something like friend class from C++ in PHP.

I found PHP :: Request #34044 :: Support for friend classes, which worked for a simple example, but not for bigger ones, so I extended it.

First, I needed to extend it to work with methods and not just attributes, then with inherited classes, because I needed it in several classes and didn’t wanted to copy/paste the same code, so I started with some modification :

a) first implementation of the __call() magic method

+/- a new method, based on the one from the Feature Request

public function __call($name, $arguments)
{
$trace = debug_backtrace();
if(isset($trace[0]['class']) && in_array($trace[0]['class'], $this->__friends)) {
return call_user_func_array(array($this, $name), $this->arguments);
}
}

but it only worked for the same class, not with inherited ones. Code was copy/pasted for the __callStatic() magic method, with simple $this to get_class($his) change.

b) to access private attributes when not in the same class:

+/- inside the if of the __get() magic method

$rc=new ReflectionClass($this);
$prop=$rc->getProperty($key);
$prop->setAccessible(true);
$res=$prop->getValue($this);
return $res;

so now, it works for *THE* direct inherited classes, but not their own inherited classes. Code was copy/pasted for the __set() magic method, with simple getValue to setValue change.

c) to call private methods when not in the same class

+/- inside the if of the __call() magic method

$rc=new ReflectionClass($this);
$meth=$rc->getMethod($name);
$meth->setAccessible(true);
$res=$meth->invokeArgs($this, $arguments);
return $res;

Code was copy/pasted for the __callStatic() magic method, with simple $this to NULL change.

d) allow inherited classes to work

+/- in all __get __set __call __callStatic methods, until the if, included

$trace = debug_backtrace();
$frame=0;
while($frame<count($trace) && $trace[$frame]['class']==__CLASS__) $frame++;
if(isset($trace[$frame]['class']) && in_array($trace[$frame]['class'], $this->__friends)) {

Finally, it works when a private method access a private attribute & so forth, from friend classes only.

Code should be compatible with PHP 5+, preferably 5.1+. __callStatic was added in 5.3.

Concevoir un site comme celui-ci avec WordPress.com
Commencer