Computerworld

Objects and PHP

The focus of object orientation is the logical grouping of related variables into a generic variable - an object. Before you can create an object, however, you must create a class.

Python vs. PHP: Choosing your next project's language

A class is a template for an object. The following class, Vehicle, is designed to describe attributes of 'any' vehicle.

01	<?
02	class Vehicle
03	{
04 var $doors;
05 var $colour;
06 var $name;
07 var $price;
08
09 function Vehicle($doors,$colour,$name,$price)
10 {
11 $this->doors = $doors;
12 $this->colour = $colour;
13 $this->name = $name;
14 $this->price = $price;
15 }
16
17 function expensive()
18 {
19 if($this->price > 40000)
20 return true;
21 else
22 false;
23 }
24
25 function print_vehstr()
26 {
27 echo "{$this->name}: {$this->colour} {$this->doors} door for \${$this->price}\n";
28 }
29 }
30		 ?>

Notice how the class Vehicle looks like a regular function. Unlike a function, however, it has functions declared inside it.

The second line declares the class, which is called Vehicle. Lines four through seven declare 'properties' of the Vehicle class. Those properties - $doors, $colour, $name and $price - refer to four generic attributes of any vehicle with which our application deals. The remainder of the class definition consists of the declaration of three 'methods': Vehicles(), expensive() and print_vehstr().

The Vehicle() method is called a 'constructor'. We know it is a constructor because it has the same name as the class, Vehicle. Constructors are executed when an object is created out of the class. It sets up the object with any data necessary for use by the script - hence the name, constructor. This constructor sets the class properties declared on lines four through seven. It references these properties via the object $this, which is a reference to the object itself.

The next method, declared on line 17, tells the user whether the vehicle is expensive or not. To do so, it checks whether the $price property is greater than 40000. If so, it returns true - telling the user that the vehicle is expensive; otherwise, it returns false. Again, the method references the class property via the $this object.

The final method, print_vehstr(), prints out a vehicle string containing all properties. The following lines create an object from the Vehicle class.

01 <HTML>
02 <BODY>
03 <?
04 $car = new Vehicle(2,"red","Sport's car",60000.00);
05 if($car->expensive()) {
06 echo "An expensive vehicle\n";
07 } else {
08 echo "Not an expensive vehicle\n";
09 }
10 $car->print_vehstr();
11 ?>
12 </BODY>
13 </HTML>

The fourth line creates an object, $car, from the Vehicle class. The script passes four variables corresponding to the variables in the constructor. (When there is no class constructor, no variables need be passed.)

Line five tests whether the vehicle is expensive and, if so, tells the user. Otherwise, the user is told that the vehicle is not expensive. Finally, on line 10, we print the vehicle string.

You may be wondering why we've gone to all this trouble for such a basic application when the following script would have sufficed.

01 <HTML>
02 <BODY>
03 <?
04 $doors = 2;
05 $colour = "red";
06 $name = "Sport's Car";
07 $price = 60000.00;
08
09 if($price > 40000) {
10 echo "An expensive vehicle\n";
11 } else {
12 echo "Not an expensive vehicle\n";
13 }
14 echo "$name: $colour $doors door for \$$price\n";
15 ?>
16 </BODY>
17 </HTML>

Consider, a situation where there are 10 different vehicles. How would you group the relevant variables? A good project to learn more about objects would be to implement two applications: one using objects, the other standard PHP, but with each storing data on 10 different vehicles. You will quickly see how useful objects can be.

Page Break

Objects and PHP: Part II

On the previous page we introduced the important topic of objects and PHP; this time around we turn to more sophisticated aspects of this technology.

Extending classes

A popular aspect of object orientation is class extension, or inheritance, as it is sometimes known. Class extension allows PHP developers to add specific functions to otherwise generic classes. In non-trivial applications this is highly desirable, since it allows developers to store the program logic about a concept once and reuse it as many times as is required. Consider the following:

01	<?
02	class Vehicle
03	{
04		var $doors;
05		var $colour
06		var $name;
07		var $price;
08
09		function Vehicle($doors,$colour,$name,$price)
10		{
11			$this->doors = $doors;
12			$this->colour = $colour;
13			$this->name = $name;
14			$this->price = $price;
15		}
16
17		function print_vehstr()
18		{
19			echo "{$this->name}: {$this->colour} {$this->doors} door for \${$this->price}\n";
20		}
21
22		function commission()
23		{
24			return($this->price * 0.10);
25		}
26	}
27
28	class Motorbike extends Vehicle
29	{
30		var $colour;
31		var $name;
32		var $price;
33
34		function Motorbike($colour,$name,$price)
35		{
36			Vehicle::Vehicle(0,$colour,$name,$price);
37		}
38
39		function commission()
40		{
41			return(Vehicle::commission() * 0.5);
42		}
43	}
44
45	$a = new Motorbike("red","Zx-CL",10000);
46	echo "Commission on {$a->name} is \$".$a->commission()."\n";
47	?>

This script declares two classes, Vehicle and Motorbike. Vehicle is a generic class suitable for describing any kind of automobile - from a car to a motor bike. The reuse of code is obvious here: by extending the Vehicle class, the Motorbike class makes use of the existing logic and adds only code that differs from that which already exists.

To extend a class, developers need do only two things. First, the class that is being extended must already be declared. In our example, Vehicle is declared on line two and Motorbike is declared on line 28. Second, the 'extends' keyword needs to be used, so that PHP knows that the class being declared extends another class. This can be seen on line 28.

There are other interesting things about class extension. The constructor for Motorbike, declared on line 34, calls the constructor for Vehicle. It does this so that the variables $doors, $colour, $name and $price can be passed to the base or parent class, as it is often called. Notice that $doors is set to zero, since motor bikes do not have doors!

To call the constructor for Vehicle from Motorbike, we use a hitherto unseen PHP construct: '::'. The double colon allows PHP classes to refer directly to methods in another class without having to generate objects of them. Declaring the Motorbike constructor as follows is incorrect:

function Motorbike($colour,$name,$price)
{
$veh = new Vehicle(0,$colour,$name,$price);
}

This code actually creates a new object, $veh, which is local to the constructor. The rest of the class knows nothing about it. This is why the double colon syntax was introduced.

The final aspect of the Motorbike class that you should find interesting is this: Motorbike declares a method, commission(), which is used to calculate commission due to the sales person who sells the vehicle. However, this method is already declared in the parent class, Vehicle. This is not an error; rather, the method in Motorbike is said to overwrite the method in Vehicle.

This is convenient in our script. The commission() method in Vehicle calculates commission as 10 per cent of $price. The logic is different for motor bikes, however (see lines 39 to 42). Here, commission is calculated as being half that of other vehicles. If this was not possible, the commission() method would need to be named differently for the Motorbike class. This goes against the grain of object orientation, which focuses on efficiency and reuse of code.

Classes and objects are certainly a very useful aspect of PHP. The most valuable skill to learn is how to identify systems which take advantage of classes and objects.