Polymorphism in PHP5

Polymorphism is one of the major Object Oriented Programming features (OOP) mature programming languages like C++ or JAVA implement. Though OOP experts may reasonably claim that PHP is not strictly Object Oriented (since nothing is an object in PHP unless you create it), the language has become polymorphism-ready with version PHP5.

What is polymorphism?

Its principle lies in its name : [poly-] means much, many and [-morphism] means forms, states. So, programming in a polymorphic way allows the developer to have one single object behaving differently according to its type. Practically speaking, the developer writes a base class which defines the basic features of the object and as many subclasses as necessary to build the different behaviours the object may have. Calling the same method will have the object’s children behave differently.

Here is a simple example of polymorphic design with a vehicle object. The Vehicle class has as attributes pieces of information that are found in every kind of vehicle : make, registering date, price :

Class Vehicle {

 

protected $make;
protected $date;
protected $price;
public function __construct($make,$date,$price) {
$this->make = $make;
$this->date= $date;
$this->price= $price;
}

}

Then create the plane class and the car class that will inherit the vehicle class :

Class Car Extends Vehicle {

private $engine;
private $mileage;
public function __construct($array) {
parent::__construct($array["make"],$array["date"],$array["price"]);
$this->engine = $array["engine"];
$this->mileage = $array["mileage"];
}
}

Class Plane Extends Vehicule {

private $type;
private $seats;
public function __construct($array) {
parent::__construct($array["make"],$array["date"],$array["price"]);
$this->type = $array["type"];
$this->seats = $array["seats"];
}

}

Structuring your classes that way allows you to make your OOP more abstract, thus more flexible. Changing a specific type of object after production time will be made easier and more stable.

Objects without polymorphic design

Imagine you want to create a form generator class without polymorphism :

<?php
class Form {
public function genInput($type,$name,$value) {
SWITCH($type) {
Case”text”:
print “<input type=\”text\” name=\”".$name.”\” value=\”".$value.”\” />\r\n”;
break;
Case”textarea”:
print “<textarea name=\”".$name.”\”>”.$value.”</textarea>\r\n”;
break;
}
}
}
$form = new Form(); //initialize form object
$form->genInput(“text”,”field1″,”Lorem ipsum…”); //prints <input type=”text” name=”field1″ value=”Lorem ipsum…” />
$form->genInput(“textarea”,”field2″,”Lorem ipsum…”); //prints <textarea name=”field2″>Lorem ipsum…</textarea>
?>

Objects with polymorphic design

In order to allow an object to have several forms, be it a text field or a textarea field, we need to make our class more abstract.
So, we will create an interface, an abstract class and several subclasses (depending on the type of field).
The interface will define the functions the object will perform, no matter what the function will do. But the interface will not define any functionality of the methods, it only names them. The precise functionalities of the genInput() function will be defined in every subclass.

//INTERFACE
interface Form {

public function genInput();

}

The abstract class is a class that we only partially implement. It contains abstract methods (functions) that provide some common functionalities. The rest of the necessary functionalities will be defined in the subclasses.
//ABSTRACT CLASS
abstract class Input {
protected $name;
protected $value;
public function __construct($name,$value) {
$this->name = $name;
$this->value = $value;
}
}
Then the derived classes will call the method set in the abstract class (parent::__construct()) and the method named in the interface (genInput()) :
//TEXT & PASSWORD & HIDDEN INPUT
class Text extends Input implements Form {
private $type;
private $size;
public function __construct($array) {
parent::__construct($array["name"],$array["value"]);
$this->type = $array["type"];
$this->size = $array["size"];
}
public function genInput() {
return “<input type=\”".$this->type.”\” name=\”".$this->name.”\” value=\”".$this->value.”\” size=\”".$this->size.”\” />\r\n”;
}
}
//TEXTAREA INPUT
class Textarea extends Input implements Form {
private $cols;
private $rows;
public function __construct($array) {
parent::__construct($array["name"],$array["value"]);
$this->cols = $array["cols"];
$this->rows = $array["rows"];
}
public function genInput() {
return “<textarea name=\”".$this->name.”\” cols=\”".$this->cols.”\” rows=\”".$this->rows.”\”>”.$this->value.”</textarea>\r\n”;
}
}
This is how you can create a text field :
$object = new Text(array(“type”=>”text”,”name”=>”form_id”,”value”=>$item,”size”=>20));
$hidden = $object->genInput();
Generating a textarea field looks like this :
$object = new Textarea(array(“name”=>”form_txta”,”value”=>$item ,”cols”=>20 ,”rows”=>5));
$textarea = $object->genInput();
Webliography :

Abstract classes and interfaces
Devshed polymorphism in PHP5 article
PHP5 Tutorial : Abstract classes and Interfaces
PHP5 OOP abstract classes & interfaces