Inheritance and Polymorphism in PHP: Building a Form Generator – Part I

Object Oriented Programming (OOP) is a powerful technology for designing Web applications. This article is the first in a three part series that will explain two of the bases of OOP, Inheritance and Polymorphism, and apply these principles to building an extensible form generator.

Introduction

If you ever tasted the power of Object Oriented Programming (OOP) in PHP, then you probably know that it’s an extremely useful way to manage medium and large projects, where code reusability, extendibility and maintainability are key factors that make developing Web applications a relatively painless experience. Without a doubt, with the release of PHP 5, these advantages have been greatly enhanced due to the highly improved object model (to name a few new excellent features), which turns the present and hopefully, the future of OOP in PHP bright and extremely promising.

However, when we’re talking about PHP 4, often there are complaints about the lack of support when it comes to applying OOP. Many reasons form the foundation for this criticism, such as an absence of access modifiers, lack of abstract classes and even no support for multiple inheritance. While this is all true, in fact nothing stops developers from applying OOP theory in real applications. All that you need is the knowledge to implement OOP in a fairly decent way.

Although opinions may differ (and certainly it’s out of the scope of this article), I strongly believe that the limitations present in PHP 4 are easily overcome, giving programmers a valid reason to keep using OOP in PHP programming.

Since we pushed some misconceptions out of the way, it’s time to focus our attention on two primary bases of OOP: Inheritance and Polymorphism. In the rest of this article, we’ll introduce these concepts as they are applied in PHP, with a rather practical approach, in order to find their place in a real application: building an extensible form generator.

For experienced programmers, this surely will look like a rather boring topic. However, for beginning and intermediate PHP users, this might be a straightforward way to gracefully enter the OOP arena, without feeling completely overwhelmed. Keep reading; you’ll find it’s quite worthwhile. 

{mospagebreak title=A Quick Look at Basic OOP Concepts} 

Before we go more deeply into explaining the concept of Inheritance, for those new to OOP, let’s define the concept of object itself. In the context of OO software, an object can be almost any item or concept, either a physical object (i.e. customers, users, and so forth), or conceptual objects that only exist within software, such as a text input field or a radio button.

Object-oriented software is designed and built as a set of self-contained objects, with both attributes and operations (functions) that interact to make applications work properly. In OOP parlance, attributes are Properties or variables related to the object. Operations or functions are Methods that belong to the object to perform actions for modifying itself or for some other external effect.

One of the major pillars of OOP is Encapsulation (also known as data hiding). In simple terms, access to the data within an object must be available via the object’s methods, or the interface of the object. Modifiers and accessor methods should provide a convenient way to access and modify objects properties.

Last, but not least, we need to explain Inheritance. We can create a hierarchical relationship between classes and derived subclasses. A subclass inherits properties and methods from its super class, a fact  we can use to save ourselves some work. If we write a super class that owns properties and methods, and then create subclasses that use the capabilities of the super class, we write it only once, and this is definitely better than writing those methods and properties on each subclass (many times, in other words).

If a sentence about two classes makes sense with “is a” between the classes, from bottom to top, inheritance can probably be implemented appropriately. Consider that if we have an input text element, it might be thought of as “is a form element.” So, if we would have a form element class, then the input text element can inherit from the form element.

For clarifying the concept of Inheritance, let’s show a simple and quick example, since the topic has been thoroughly covered in many books and articles. First, let’s define a base class “basicMessage” for, not surprisingly, displaying messages:

class basicMessage {

var $message;

function basicMessage($message){

$this->message=$message;

}

function displayMessage(){

echo ‘Displaying ‘.$this->message.’ from base class<br />’.”n”;

}

}

 

Now, let’s instantiate an object from the base class:

 

$msg=&new basicMessage(‘Hello, I am the Mom’);

$msg->displayMessage();

 

The output for the above code is the following:

Displaying Hello, I am the Mom from base class

That’s very simple and straightforward, right? Now, in order to implement Inheritance, let’s define a subclass “boldedMessage,” which inherits the properties and methods from “basicMessage:”

class boldedMessage extends basicMessage {

function boldedMessage($message){

parent::basicMessage($message);

}

}

 

Please notice that inside the “boldedMessage” constructor, we’ve called the constructor for “basicMessage,” with the following syntax:

parent::basicMessage($message);

Now, if we instantiate an object from the subclass “boldedMessage,” in the following manner:

$childmsg=&new boldedMessage(‘Hello, I am the child’);

$childmsg->displayMessage();

The visual output is as follows:

Displaying Hello, I am the child from base class

Certainly, the subclass is happily inheriting the $message property and the “displayMessage()” method from the base class. Also, for proper implementation, the base class definition must be available, for deriving any number of subclasses. Please don’t forget that!

If we ever change our mind, and decide to add the own “displayMessage()” method to the subclass “boldedMessage,” overriding the original base class method, the class definition would look like this:

class boldedMessage extends basicMessage {

function boldedMessage($message){

parent::basicMessage($message);

}

//override base class displayMessage() method

function displayMessage(){

echo ‘<strong>Displaying ‘.$this->message.’ from subclass</strong><br />’.”n”;

}

}

By this point, the subclass is overriding the “displayMessage(),” exposing its own method definition, in this case displaying a bolded message. Just by instantiating a new object from the redefined class, in a similar way to the previous examples:

$childmsg=&new boldedMessage(‘Hello, I am the child’);

$childmsg->displayMessage();

the output would be a bolded string message:

Displaying Hello, I am the child from subclass 

As you can see, any number of derived subclasses from the base class will inherit its properties and methods. Indeed, this is extremely useful in OOP. Just think about it. If we have a super class containing the core properties and methods, and for instance, we need to add another method to it, the new method will be automatically inherited from all of the defined subclasses. If you think that’s not enough power, well you should run for president!

Now let’s take a more practical approach and use OOP in PHP to build something useful for Web applications. Did you read this article’s title? Okay, we’re going to develop an extensible form generator, using the goodies of Inheritance and Polymorphism. Keep reading.

{mospagebreak title=The Base Class of the Form Generator}

Having learned a bit more about Inheritance in PHP, we’re going to establish the basics for our form generator. First, we should define a base class called “formObject,” which sets the blueprints for any generic form element, that is, input text fields, radio buttons, checkboxes and the like. Doing so, whenever we need to create a new specific form element, by just deriving a new subclass from the base class, we can generate as many form elements as we want.

Let’s start by defining the base class “formObject,” which exposes three properties common to all of the form elements: a label, a name, and a style. Of course, we may add a few more properties, such as an ID, but for now we’ll just keep it this way. This the first definition for the base class “formObject”:

class formObject {

var $label;

var $name;

var $style;

function formObject($label,$name,$style){

// setup tasks performed here

}

}

As you can see, the base class is very simple. We have defined three common properties for it, $label, $name and $style, respectively. Then, as we usually do in PHP 4, the constructor is properly defined, accepting the three parameters previously mentioned. Correct me if I’m wrong, but this class is simply doing nothing. All right, let’s extend the class definition to add more functionality to it. Here’s the improved class:

class formObject {

var $label;

var $name;

var $style;

function formObject($label,$name,$style){

(!is_numeric($label))?$this->label=$label:die(‘Invalid parameter ‘.$label);

(!is_numeric($name))?$this->name=$name:die(‘Invalid parameter ‘.$name);

(!is_numeric($style))?$this->style=$style:die(‘Invalid parameter ‘.$style);

}

}

Now the class is beginning to look more appealing, since it’s performing some useful initializing tasks. The constructor is now checking the validity of each possible parameter, before assigning them as class properties. We’ve decided to consider as valid arguments any non-numeric value, for being assigned to the properties $label, $name and $style. If any of them are numeric values, the class simply kills execution by calling the “die()” function.

As you can see, we’re not being very restrictive about the possible values assigned to each property, only allowing them to be non-numeric values. The reason for doing this is that we simply don’t want any label value looking like 12120, or names such as -12.8, included in the HTML markup. You get the idea. But since the code is easily extensible, you might add your own validation rules for incoming parameters.

So far, the class is setting up the $label, $name and $style properties, which are common to each possible form element. Now, we need to define a method for generating the corresponding HTML code for every form object. So, let’s be more specific here. Since we’re going to use this base class for creating all of the derived subclasses, the method for building the HTML should be generic, displaying a warning message, so that it won’t be overridden on each subclass. We’ll see it more clearly in detail later. For now, let’s define the generic method “generateHTML()” in the following way:

function generateHTML(){

echo ‘You are not overriding the generateHTML() method of the formObject super class!';

}

This last method finally structures our base class “formObject” as follows:

class formObject {

var $label;

var $name;

var $style;

function formObject($label,$name,$style){

(!is_numeric($label))?$this->label=$label:die(‘Invalid parameter ‘.$label);

(!is_numeric($name))?$this->name=$name:die(‘Invalid parameter ‘.$name);

(!is_numeric($style))?$this->style=$style:die(‘Invalid parameter ‘.$style);

}

function generateHTML(){

echo ‘You are not overriding the generateHTML() method of the formObject super class!';

}

}

That’s fairly good. Our base class “formObject” is finally finished and it’s doing a nice job, because it is defining the common properties for the future derived subclasses that will build each specific form element. Please don’t feel disappointed about the class code. Were you expecting hundreds of lines? Remember that we’re going to implement the power of Inheritance in PHP to create the subclasses for radio buttons, checkboxes, input text elements and even more. Thus, let’s take a look at the structure of each derived subclass.

{mospagebreak title=Applying Inheritance: Creating Subclasses}

Having defined the generic base class for the form generator, it’s fairly easy to derive any number of subclasses tied to each particular form element. After all, that’s the big advantage of Inheritance. From this point onward, every defined subclass will inherit the $label, $name and $style properties, previously defined within the super class, as well as the “generateHTML()” method. Let’s make Inheritance work for us and define the subclasses for building the form generator. Here are the initial definitions for the each form element’s class:

// class definition for input text object

class inputTextObject extends formObject {

var $value;

var $maxlength;

function inputTextObject($label,$name,$style,$value,$maxlength){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for hidden field object

class hiddenFieldObject extends formObject {

var $value;

function hiddenFieldObject($label,$name,$style,$value){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for radio button object

class radioButtonObject extends formObject {

var $value;

var $checked;

function radioButtonObject($label,$name,$style,$value,$checked=”){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for checkbox object

class checkBoxObject extends formObject {

var $value;

var $checked;

function checkBoxObject($label,$name,$style,$value,$checked=”){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for select box object

class selectObject extends formObject {

var $size;

var $options;

function selectObject($label,$name,$style,$size,$options=array()){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for textarea object

class textAreaObject extends formObject {

var $value;

var $wrap;

function textAreaObject($label,$name,$style,$value,$wrap=’virtual’){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for button object

class buttonObject extends formObject {

var $value;

function buttonObject($label,$name,$style,$value){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for password object

class passwordObject extends formObject {

var $maxlength;

function passwordObject($label,$name,$style,$maxlength){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for file object

class fileObject extends formObject {

function fileObject($label,$name,$style){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for image object

class imageObject extends formObject {

var $value;

var $src;

var $alt;

function imageObject($label,$name,$style,$value,$src,$alt){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

// class definition for submit object

class submitObject extends formObject {

var $value;

function submitObject($label,$name,$style,$value){

parent::formObject($label,$name,$style);

// properties setup

}

function generateHTML(){

}

}

Phew, I think that’s the entire list for subclass definitions. In the above listing, we’ve implemented Inheritance by creating the proper subclasses that extend the original “formObject” base class, in order to generate the different form elements. Now, our form generator is beginning to be progressively modeled. While the subclasses have been defined with empty “generateHTML()” methods, as you can guess, the final version will include the logic for generating the HTML code for every specific element. For now we’ll keep it pretty skeletal, which is handy for keeping the code easily readable.

Summary

And that’s it for now. In this first part, we’ve been glancing at one of the big pillars of OOP in PHP, Inheritance. We’ve been using its capabilities for building an extensible form generator. Starting from a generic “formObject” base class, we’ve extended its definition to derive the needed subclasses.

Hopefully this has been a practical approach to demonstrate the use of inherited methods and properties and their correct syntax. However, the best part is coming up. In the second part of this article series, we’ll be exposing the complete source code for each subclass and explaining another core concept of OOP: Polymorphism. In the meantime, have some fun classing with PHP!

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort