Created
April 26, 2011 14:52
-
-
Save fatmatto/942406 to your computer and use it in GitHub Desktop.
Pretending multiple inheritance in php5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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