Skip to content

Instantly share code, notes, and snippets.

@fatmatto
Created April 26, 2011 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatmatto/942406 to your computer and use it in GitHub Desktop.
Save fatmatto/942406 to your computer and use it in GitHub Desktop.
Pretending multiple inheritance in php5
<?php
namespace qoo\core;
/**
*
* Simple abstract class that virtually "inherit" methods and properties from other classes.
*
* It's virtual because it adds nothing more to your class definition.
* It just add methods runtime.
*
* @author Mattia Alfieri <mattia.alfieri@ymail.com>
* @license BSD
*
**/
abstract class MultipleInheritant
{
/**
*
* @var mixed Array of instanced superclasses
*
**/
protected $_Superinstances = array();
/**
* Initialize this array with names of classes you want to inherit
* @var mixed Array of superclasses names
*
**/
protected $_Superclasses = array();
/**
*
* Constructor, if you override the constructor, remember to
* call parent::__construct() or you will lose automatic inheritance
* through the $_Superclasses array
*
*
**/
public function __construct() {
foreach ($this->_Superclasses as $superclass)
{
$this->inherit($superclass);
}
}
/**
*
* 'Inherits' $class, this means that you
*
*
**/
public function inherit($class)
{
if (is_object($class) )
array_push($this->_Superinstances,$class);
elseif (is_string($class) && class_exists($class))
array_push($this->_Superinstances,new $class());
elseif(is_string($class) && !class_exists($class))
throw new \qoo\core\Exception("$class is not a classname");
else
throw new \qoo\core\Exception("You can inherit only classnames or instances");
}
private function LookForClassWithMethod($object,$method)
{
if (method_exists($object,$method) )
return $object;
if (is_subclass_of($object,'/qoo/core/MultipleInheritant') OR is_subclass_of($object,'\qoo\core\MultipleInheritant'))
{
foreach( $object->getInheritedInstances() as $inherited)
{
$result = $this->LookForClassWithMethod($inherited,$method);
if (null !== $result)
return $result;
}
}
else
return null;
}
private function LookForClassWithProperty($object,$property)
{
if (property_exists($object,$property) )
return $object;
if (is_subclass_of($object,'/qoo/core/MultipleInheritant') OR is_subclass_of($object,'\qoo\core\MultipleInheritant'))
{
foreach( $object->getInheritedInstances() as $inherited)
{
$result = $this->LookForClassWithProperty($inherited,$property);
if (null !== $result)
return $result;
}
}
else
return null;
}
/**
* Returns instances of inherited objects
*
*
**/
public function getInheritedInstances()
{
return $this->_Superinstances;
}
public function __call($method,$args = array())
{
$super = $this->LookForClassWithMethod($this,$method);
if (null === $super)
throw new \Exception('Call to undefined method <b>'.$method.'</b> in class <b>'.get_class($this).'</b>' );
switch (count($args) )
{
case 0:
$super->$method();
break;
case 1:
$super->$method($args[0]);
break;
case 2:
$super->$method($args[0],$args[1]);
break;
case 3:
$super->$method($args[0],$args[1],$args[2]);
break;
case 4:
$super->$method($args[0],$args[1],$args[2],$args[3]);
break;
case 5:
$super->$method($args[0],$args[1],$args[2],$args[3],$args[4]);
break;
case 6:
$super->$method($args[0],$args[1],$args[2],$args[3],$args[4],$args[5]);
break;
case 7:
$super->$method($args[0],$args[1],$args[2],$args[3],$args[4],$args[5],$args[6]);
break;
case 8:
$super->$method($args[0],$args[1],$args[2],$args[3],$args[4],$args[5],$args[6],$args[7]);
break;
default:
throw new \Exception('The inherited method '.$method.' in class '.get_class($this).' has too many arguments to be handled by qoo\core\MultipleInheritant' );
break;
}
}
/**
*
* Looks for a superclass with the requested property
*
* @param string $property The name of the property
**/
public function __get($property)
{
$super = $this->LookForClassWithProperty($this,$property);
if (null === $super)
throw new \Exception('Call to undefined property named '.$property);
return $super->{$property};
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment