PHP for OO development

This article was originally published in VSJ, which is now part of Developer Fusion.
PHP is an open source scripting language that you can download and use with most web servers working on Windows or Linux. What is interesting about PHP is that it provides an alternative ‘world view’ of how web development should proceed, but many PHP programmers simply ignore its most powerful feature – it is fully object oriented. In the past this probably wasn’t a big consideration, as its handling of objects wasn’t particularly efficient. Version 5 introduced some changes, such as passing objects by reference instead of by value, that have improved efficiency to the point where it is practical to use object oriented architectures within PHP pages. Let’s take a look at how PHP handles objects.

If you want to try out PHP, simply download it from www.php.net. If you’re using Windows, simply follow the installer’s prompts and select the web server you are using.

Class and objects

If you have been using scripting in web pages you might think that object-oriented programming is overkill for most of what you want to do. You can, of course, opt to use PHP without ever worrying about objects, but they aren’t difficult to work with, and they provide a way of organising your code so that it is easier to reuse and modify. The following tutorial should give you a clear idea of what objects have to offer.

Before we get started it is important to distinguish between a class and an object. A class is a specification for an object, and once you have created a class you can use it to create as many objects, of that type, as you need. In this sense a class doesn’t actually do anything. It isn’t executable PHP code. It basically just sits there waiting for someone to make use of it. For example, let’s suppose we need a calculator that can be used in any web page. So we might well proceed by defining a calculator class.

<?php
class Calculator
{
}
?>
The class keyword is used to create a new class, and the definition of the class goes between the curly brackets. In general an object can have properties and methods. You can think of properties as being values or variables that relate to the object. For a calculator a property must be a variable like $answer, which could be used to record the last answer. Properties behave like variables that belong to the class or object. They have to be declared using the var keyword.

For example, to give the calculator class an “answer” property, initialised to zero, you would write:

<?php
class Calculator
{
	var $answer=0;
}
?>
Now that we have a class with a property, we can try it out. To create an object from a class we use the new command:
$mycalc=new Calculator;
Whenever you have a class you can use the same sort of instruction to create an instance of the class. You can create as many instances of a class you require. Once you have created an instance you can access its properties using expressions like:
$mycalc->answer
This can be read as “mycalc’s answer property”. Properties can be used just like variables. For example:
$mycalc->answer=10;
Print $mycalc->answer;
Every instance of a class you create has its own properties and methods. For example, if you try:
$mycalc1=new Calculator;
$mycalc2=new Calculator;
$mycalc1->answer=10;
$mycalc2->answer=20;
Print $mycalc1->answer;
Print $mycalc2->answer;
…then you will see 10 and 20 printed. This demonstrates that each instance is a complete and distinct incarnation of the class that you have defined.

Methods

Things really start to get interesting when you add methods to classes. Roughly speaking, a property is something that a class has as a value, and a method is something that a class can do. You need to think of this difference as being like nouns and verbs. For example, a ball class might have a colour property and a bounce method, i.e. some code that makes it bounce. In other words, methods are what your class does.

In PHP, methods are implemented using standard functions. For example, our calculator class can quite easily have an add method added to it:

<?php
class Calculator
{
	var $answer=0;
	function add($a,$b)
	{
		return $a+$b;
	}
}
?>
Now we can create an instance of the class and use its add method:
$mycalc = new Calculator;
print $mycalc->add(1,2);
Notice that methods are accessed using the same “->” notation. As in the case of properties such as $answer, each instance of the class gets its own private copy of add, or any other method for that matter. You really do have to think of a class as a specification for creating an object.

This?

That’s more or less all there is to basic objects in PHP, but there are some subtle points that we need to cover to make sure that you know how everything works. The first little problem to overcome is how does a class refer to its own methods and properties. You might think that the following would work just fine:
<?php
class Calculator
{
	var $answer=10;
	function add($a,$b)
	{
		$answer=$a+$b;
		return $answer;
	}
}
?>
But $answer in the function add isn’t the same as the $answer property defined outside of the function. You can check this by adding the following lines:
$mycalc=new Calculator;
print $mycalc->add(1,2);
print $mycalc -> answer;
You will see 3 and 10 printed out, demonstrating that the add method doesn’t change the answer property. If you want a class method to use a property or another method then you have to make use of the “$this” keyword, as in
$this->answer=$a+$b;
When you create an instance of a class $this gets set to point to the instances, properties and methods. The correct way to set the answer property in the Calculator class is:
<?php
class Calculator
{
	var $answer=10;
	function add($a,$b)
	{
		$this->answer=$a+$b;
		return $this->answer;
	}
}
$mycalc=new Calculator;
print $mycalc->add(1,2);
print $mycalc -> answer;
?>

Constructors

Another detail of using classes and objects is the constructor. A constructor is simply a special method which is called when an instance of the class is created. The constructor is essentially an initialisation routine, and it is identified by having the same name as the class. For example:
function Calculator()
{
	$this->answer=0;
}
…is a constructor for the Calculator class, that simply sets the answer property to zero. Constructors can have parameters. For example:
function Calculator($a)
{
	$this->answer=$a;
}
This constructor sets the answer property to whatever $a is at the time an instance is created. This raises the question of how you specify parameters when you create a class with such a constructor. The answer is that you simply include the parameters in the line that creates the object. For example:
$mycalc=new Calculator(4);
…creates an instance of the calculator class with answer set to 4. If you give a class a constructor with parameters then you have to make use of it when you create an instance.

Inheritance

Put simply, the basic idea of inheritance is to use an existing class to build a new class that is a customisation or extension of it. For example, let’s suppose that the Calculator class is completely finished and working and we need a special type of calculator – perhaps a scientific calculator. We could take all of the PHP code in the Calculator class and use it to create a new SciCalc class using nothing but copy and paste. We could add methods and even modify existing methods “inherited” via copy and paste from Calculator. This all works, but it produces a problem for the future. Now we have two sets of more or less identical code – Calculator and the code we copied and pasted into SciCalc. Now imagine what happens when an error is found in Calculator. You will have to make any changes that fix the error in Calculator in SciCalc and vice versa. In short you now have two copies of more or less the same code to debug and maintain – not good.

Inheritance as implemented in most object-oriented languages is just an attempt to improve on copy and paste by keeping the relationship between the classes alive. For example, in PHP you could create the SciCal class, which inherits everything Calculator has, using:

class SciCal extends Calculator
{
}
Following this, and even without writing a single line of code, SciCal has all of the methods and properties of Calculator. That is, if you create an instance of SciCal the object can be used exactly if it was an instance of Calculator. This is just like the copy and paste replication, only now if you make any changes to Calculator these are passed on immediately to SciCal without you having to do anything about it.

What do you do, however, if you want to change the way an inherited method works? The answer is that you can override it by simply providing a new definition. For example, if (for example) the SciCal class needed to implement an addition method which worked to a higher precision, then it would simply include a new definition of the method. Any inherited methods that are redefined in this way are replaced or ‘overridden’ by their new definition.

There are a couple of minor points we need to deal with. The first is that when you override a method it isn’t destroyed – it still exists, but the new method is used in place of it. PHP, and most object-oriented languages, provide a mechanism whereby you can make use of the original version of the method if you really want to. All you have to write is parentclass::method(). For example, if you have overridden add in the SciCal class which inherits from Calculator then, within the new add function, you could write:

$ans=Calculator::add($a,$b);
…to call the original add method. Notice that you can only use this syntax within the SciCal class.

Another subtle point is what happens to constructors when a class is inherited? The answer depends on whether or not you provide a constructor for the new class. If you don’t provide a constructor and the base class has one then it is called automatically. That is, if the Calculator class has a constructor which takes one parameter then so does SciCalc, and you have to create an instance of the class using:

$mycalc=
	new SciCalc(1);
…even if you haven’t defined a constructor for SciCalc.

If you do define a constructor for the new class then it is used, and the base class’s constructor isn’t automatically called. Of course you can use Calculator::Calculator() in the new class to explicitly call it – but you don’t have to.

In all of this discussion you need to keep in mind that you can use inheritance more than once. That is, class A can be derived from class B, which was derived from class C and so on.

A button pad HTML object

It is difficult to give a really good example of how to make use of the object-oriented features of PHP – or indeed any object-oriented language. The reason is that the real advantages of the object-oriented approach really only become clear when the project is large and complicated – and large and complicated examples generally aren’t clear! To give you some idea of how you might go about using the object-oriented approach in PHP, let’s build a simple class which generates a particular HTML object. A common requirement is a set of buttons arranged in a grid – hence our class is called buttonpad. Given that our earlier example involved a calculator, you can see that a buttonpad object might well form the basis of a calculator object’s user interface.

The start of the class simply defines some variables that are used:

<?php
class buttonpad
{
	var $hor;
	var $ver;
The $hor and $ver properties are going to be used to store the dimensions of the button grid. You can save the code for the class in a file called “buttonpad.inc” for use in a PHP page.

Getting just a little more advanced, we can also make use of an array to store the labels that are going to be displayed on each of the buttons. This array can be accessed to set the labels, or methods can be provided to set it automatically:

	var $names=array();
The constructor simply sets the size of the buttonpad n x m buttons:
	function buttonpad($n,$m)
	{
		$this->hor=$n;
		$this->ver=$m;
	}
As an example of a method to set the button labels automatically, the following sets them to 1,2,3,4 and so on reading right-to-left and top-to-bottom:
	function SetSequentialLabels()
	{
		$count=1;
		for($y=1;$y<=$this->ver;$y++)
		{
			for($x=1;$x<=$this->hor;$x++)
			{
				$this->names[$x][$y]=$count;
				$count=$count+1;
			}
		}
	}
This complicated-looking function simply stores consecutive values in the array names.

Finally all we need is a method to generate the appropriate HTML:

	function output()
	{
		for($y=1;$y<=$this->ver;$y++)
		{
			for($x=1;$x<=$this->hor;
				$x++)
			{
				print “<input
					type=button “;
				print
	“value=”.$this->names[$x][$y].” “;
				print
					“name=B”.$y.$x.”>\n”;
			}
			print “\n<br>\n”;
		}
	}
}
?>
The only complicated part of this method is the print statement, which builds up an HTML tag something like:
<input type=button value=caption name= Browcolumn>
…where caption is the value stored in the appropriate location of the $names array, and rowcolumn is simply the row and column number that the button is in. For example, the first button is:
<input type=button value=caption name=B11>
…then:
<input type=button value=caption name=B12>
…and so on.

If you enter all of this code into the file “buttonpad.inc”, you can make use of it in a PHP page using something like:

<?php
include(“buttonpad.inc”);
?>
<html>
<head>
<title>Buttons demo</title>
</head>
<body>
<?php
$pad=new buttonpad(3,3);
$pad->SetSequentialLabels();
$pad->output();
?>
</body>
</html>
Notice that the “include” has to be the first item in the page, and that the included file has to start with <?php and end with >>. This might look complicated, but notice that the PHP program is just:
$pad=new buttonpad(3,3);
$pad->SetSequentialLabels();
$pad->output();
…and this generates a 3x3 labelled grid of buttons (see Figure 1).

Figure 1
Figure 1: A button grid generated by a PHP class

Of course there are lots of big and small improvements you can make to the class. For example, it seems to make sense to allocate a default labelling for the buttons, and this is best done in the constructor:

function buttonpad($n,$m)
{
	$this->hor=$n;
	$this->ver=$m;
	$this->SetSequentialLabels();
}
It is very easy to create PHP classes that make use of state or session information. This makes it possible to take an object-oriented approach to problems such as user tracking – simply define a User class, and create an instance for each user. In the same way, you could build a shopping system based on a shopping cart class, and so on. And when it comes to database manipulation, objects were just made for the job! The point is that there are times when an object-oriented approach really is justified, and other times when you are probably better off just writing PHP script functions.


Harry Fairhead is the author of various books and articles on computer architectures. His current interests include heterogeneous systems and embedded web programming, mostly using PHP.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“My definition of an expert in any field is a person who knows enough about what's really going on to be scared.” - P. J. Plauger