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.