PHP has limited support for object-oriented programming and allows programmers to define their own classes and create object instances of those classes. We make little use of objects in this book, and this section serves as an introduction to PHP's support of object-oriented features. The subject of object-oriented programming is extensive, and we don't provide a complete explanation of the subject here.
A class defines a compound data structure made up of member variables and a set of functions—known as methods or member functions—that operate with the specific structure. Example 2-7 shows how a class Counter is defined in PHP. The class Counter contains two member variables—the integers $count and $startPoint—and four functions that use these member variables. Collectively, the variables and the functions are members of the class Counter.
<?php // A class that defines a counter. class Counter { // Member Variables var $count = 0; var $startPoint = 0; // Methods function startCountAt($i) { $this->count = $i; $this->startPoint = $i; } function increment( ) { $this->count++; } function reset( ) { $this->count = $this->startPoint; } function showvalue( ) { print $this->count; } } ?>
To use the data structures and functions defined in a class, an instance of the class—an object—needs to be created. Like other data types—integers, strings, arrays, and so on—objects are held by variables. However, unlike other types, objects are created using the new operator. An object of class Counter can be created and assigned to a variable as follows:
$aCounter = new Counter;
Once the variable $aCounter is created, the member variables and functions of the new object can be used. Members of the object, both variables and functions, are accessed using the -> operator. Consider the following example:
echo $aCounter->count; // prints 0 $aCounter->increment( ); echo $aCounter->count; // prints 1 // Bypass the function that updates count $aCounter->count = 101;
In the class definition, the code that defines member functions can access the member variables with the variable $this as can be seen in the Counter function implementations in Example 2-7. The variable $this has special meaning and acts as a placeholder until a real object is created. For example, when the function $aCounter->increment( ) is called, the variable $this acts as $aCounter.
By placing the code shown in Example 2-7 in the file counter.inc, the class Counter can be used by other scripts to create new objects, as shown in Example 2-8.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head><title>Counter</title></head> <body> <?php include "counter.inc"; // Create a new object of type "counter" $temp = new Counter; // Set the counter to 10 $temp->startCountAt(10); // Increment the counter $temp->increment(); $temp->increment(); $temp->increment( ); // Print out the value of the counter echo "<p>Counter is now: "; $temp->showvalue( ); // Reset the counter $temp->reset( ); // Print out the value of the counter echo "<p>Counter is now: "; $temp->showvalue( ); ?> </body></html>
Many objects of the same class can be created. For example, you can use the following fragment to create three objects and assign them to three variables:
$a = new Counter; $b = new Counter; $c = new Counter;
The variables $a->count, $b->count, and $c->count are different. Each variable is of type object and references an object of the class Counter, but the objects themselves are independent.
One of the powerful concepts in object-oriented programming is inheritance. Inheritance allows a new class to be defined by extending the capabilities of an existing base class. PHP allows a new class to be created by extending an existing class with the extends keyword. Example 2-9 shows how the class Counter is extended to create the new class BottleCounter that can determine the number of cases of wine to be shipped.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head><title>Bottle Counter</title></head> <body> <?php include "counter.inc"; class BottleCounter extends Counter { // Add 12 bottles to the counter function addCase( ) { $this->count += 12; } // Return the number of cases to be shipped function caseCount( ) { return ceil($this->count / 12); } // A Constructor that sets the initial count function BottleCounter($startCount) { $this->count = $startCount; } } // Create a new object of type "BottleCounter" // and pass the initial count of 12 $temp = new BottleCounter(12); // Increment the counter $temp->increment( ); // Add another Case $temp->addCase( ); // Print out the value of the counter: 24 echo "<p>Counter is now: "; $temp->showvalue( ); // Print the number of cases $cases = $temp->caseCount( ); echo "<p>The number of cases to ship: $cases"; ?> </body></html>
The new class BottleCounter doesn't add any new member variables but does add three new member functions. The functions of the class BottleCounter use the member variables of the base class Counter in ways appropriate to BottleCounter. The function addCase( ) increments the $count variable by 12, and the function caseCount( ) returns the total number of cases that need to be shipped, including any partially filled cases.
The final function, BottleCounter( ), is the constructor of the class BottleCounter. Member functions with the same name as the class are treated differently. PHP uses these functions as constructors, and they are called when new objects of that class type are created. A constructor function can include arguments that can be used to initialize member variables when a new object is created. Example 2-9 showed how a new BottleCounter object is created:
// Create a new object of type "BottleCounter" // and pass the initial count of 12 $temp = new BottleCounter(12);
The power of inheritance doesn't come from simply reusing code. Objects created from the extended class can be used as if they were created from the existing base class. This ability to use an object as if it were an instance of the base class is known as polymorphism. You can use the class Counter as a base for other new classes, such as a CanCounter class in which a case is 24 cans, not 12 bottles. Code that uses an object of class Counter can then be used with objects of type BottleCounter or CanCounter. Consider this example, which defines the function volumeDiscount( ), designed to return a discount factor based on a Counter object:
// Return a discount factor based on // the value of the Counter $var function volumeDiscount($var) { // use $var as a Counter if ($var->count > 24) return 0.95; else return 1.0; } $bottles = new BottleCounter(10); $cans = new CanCounter(24); $bottleDiscountFactor = volumeDiscount($bottles); $canDiscountFactor = volumeDiscount($cans);
If both the BottleCounter and CanCounter classes are defined as extensions of Counter, the function volumeDiscount( ) can be called on objects of those classes.
Copyright © 2003 O'Reilly & Associates. All rights reserved.