Skip to content

Instantly share code, notes, and snippets.

@motanelu
Created January 21, 2012 12:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save motanelu/1652646 to your computer and use it in GitHub Desktop.
Save motanelu/1652646 to your computer and use it in GitHub Desktop.
Multiple Inheritance in PHP
<?php
/**
* Abomination class implementing multiple inheritance via
* __call magic method
*/
abstract class MultipleInheritance
{
/**
* List of parent classes
*
* @var array
* @access protected
*/
protected $_parents = array();
/**
* List of parent objects - generated automatically
*
* @var array
* @access private
*/
private $_parentObjects = array();
/**
* Constructor (thank you captain Obvious :)
*
* - init the parent objects
*
* @access public
*/
public function __construct()
{
foreach ($this->_parents as $parentClass) {
$this->_parentObjects []= new $parentClass();
}
}
/**
* __call magic method
*
* @param string $name
* @param array $arguments
* @access public
* @return mixed
*/
public function __call($name, array $arguments)
{
foreach ($this->_parentObjects as $object) {
if (is_callable(array($object, $name))) {
return call_user_func_array(array($object, $name), $arguments);
}
}
throw new Exception('No such method: ' . $name);
}
/**
* __set magic method
*
* @param string $key
* @param mixed $value
* @access public
* @return void
*/
public function __set($key, $value)
{
foreach ($this->_parentObjects as $object) {
// isset() misses null properties
if (property_exists($object, $key)) {
$object->{$key} = $value;
return;
}
// property_exists() misses magic properties
if (isset($object, $key)) {
$oject->{$key} = $value;
return;
}
}
}
/**
* __get magic method
*
* @param string $key
* @access public
* @return mixed
*/
public function __get($key)
{
foreach ($this->_parentObjects as $object) {
if (property_exists($object, $key) || @$object->{$key}) {
return $object->{$key};
}
}
}
/**
* Check inheritance
*
* @param string $class
* @access public
* @return bool
*/
public function isInstanceOf($class)
{
if (in_array($class, $this->_parents)) {
return true;
}
foreach ($this->_parentObjects as $parent) {
if ($parent instanceof MultipleInheritance) {
if ($parent->isInstanceOf($class)) {
return true;
}
}
}
return false;
}
}
/**
* Example classes:
*/
class Dad
{
public $familyName = 'Smith';
/**
* Can parallel park
*
* @access public
* @return void
*/
public function park()
{
echo 'Look, I can parallel park' . PHP_EOL;
}
/**
* Can ground the kids
*
* @access public
* @return void
*/
public function ground()
{
echo 'Grounded by DAD' . PHP_EOL;
}
}
class GrandMa
{
public $familyName = 'Doe';
/**
* Knows bed-time stories
*
* @access public
* @return void
*/
public function tellStory()
{
echo 'When I was your age...' . PHP_EOL;
}
/**
* __isset
*
* @param string $key
* @access public
* @return bool
*/
public function __isset($key)
{
if ($key == 'ancientCraft') {
return true;
}
}
/**
* __get
*
* @param string $key
* @access public
* @return mixed
*/
public function __get($key)
{
if ($key == 'ancientCraft') {
return 'knit';
}
}
}
class Mom extends MultipleInheritance
{
protected $_parents = array('GrandMa');
/**
* Makes sandwiches
*
* @access public
* @return void
*/
public function makeSandwich()
{
echo 'Just making a sandwich' . PHP_EOL;
}
/**
* Can grounds the kids
*
* @access public
* @return void
*/
public function ground()
{
echo 'Grounded by MOM' . PHP_EOL;
}
}
class Child extends MultipleInheritance
{
protected $_parents = array('Dad', 'Mom');
}
/*
Let's try it out:
*/
$child = new Child();
$child->park(); // inherited from Dad
$child->makeSandwich(); // inherited from Mom
$child->ground(); // inherited from both, but the method in the Dad class will execute
$child->tellStory(); // inherited from GrandMd
if ($child->isInstanceOf('Mom')) {
echo get_class($child) . ' class inherits from Mom' . PHP_EOL;
} else {
echo get_class($child) . ' class does not inherit from Mom' . PHP_EOL;
}
if ($child->isInstanceOf('GrandMa')) {
echo get_class($child) . ' class inherits from GrandMa' . PHP_EOL;
} else {
echo get_class($child) . ' class does not inherit from GrandMa' . PHP_EOL;
}
/**
* Stranger class
*/
class Stranger {}
if ($child->isInstanceOf('Stranger')) {
echo get_class($child) . ' class inherits from Stranger' . PHP_EOL;
} else {
echo get_class($child) . ' class does not inherit from Stranger' . PHP_EOL;
}
echo 'The child\'s family name is ' . $child->familyName . PHP_EOL;
if ($child->ancientCraft) {
echo 'The child knows to ' . $child->ancientCraft . PHP_EOL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment