07 October, 2010

How to extend more than one class in php

Since multiple inheritance is not supported in php, we have to find a way to support it, so that we will be
able to extend more than one class at once. For this we can fake multiple inheritance in php using some
class and object functions provided by php.
I came across the problem where i had to extend more than once class using a single class, and for that
after some research came to a solution that can be used to make php support multiple inheritance, if i can say that.

//this is the Abatract class that implements fake multiple inheritance in php
//not allowed to create instance of this class
Abstract class MultipleExtension {

public $_this;
private $_extension = array(); //contains extended classes

//constructor function that passes $this to our private variable $_this
function __construct(){
$_this = $this;
}

//function to add the extended class objects
public function addExtension($obj) {
$this->_extension[]=$obj;
}

//overloading the members with getter function
public function __get($name) {
foreach($this->_extension as $ext) {
//check if the property defined as $name exists in the class $ext
if(property_exists($ext,$name))
return $ext->$name;
}
}

//member overloading using setter function
public function __set($name, $value) {
foreach($this->_extension as $ext) {
//check if the property $name exists in class $ext
//and if it does assign the value in $value to $name property of $ext class
if(isset($ext->$name)) {
$ext->$name = $value;
}
}
}

public function __call($method,$arguments) {
foreach($this->_extension as $ext) {
//check if function exists defined in method variable for the extended class
if(method_exists($ext,$method)) {
//call the user defined function with method and parameters
return call_user_func_array(array($ext, $method) ,$arguments);
}
}
}
}

And below is the implementation of above abstract class that supports multiple inheritance

//this is the first class that sets firstname of a user
class First {
private $_firstName;
public function setName($firstname){
$this->_firstName = $firstname;
}
public function getName(){
return $this->_firstName;
}
}
//this is the second class that sets location of a user
class Second {
private $_locationName;
public function setLocation($location){
$this->_locationName = $location;
}

public function getLocation(){
return $this->_locationName;
}
}
//this is a test class that extends multipleExtension class that fakes multiple inheritance
class Test extends MultipleExtension {
function __construct() {
//call the function that stores all the objects of classes as shown below
parent::addExtension(new First());
parent::addExtension(new Second());
}

public function __toString() {
return $this->getName().' located in: '.$this->getLocation();
}
}
//now create object of Test class and do as follows
$obj = new Test();
$obj->setName("Sudhir");
$obj->setLocation("Nepal");
echo $obj;
//This will output Sudhir located in: Nepal.

No comments: