Tải bản đầy đủ (.pdf) (108 trang)

Beginning PHP and MySQL From Novice to Professional phần 3 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.42 MB, 108 trang )


182
CHAPTER 6
■ OBJECT-ORIENTED PHP
private function takeLunchbreak(Employee $employee)
{

}
Keep in mind that type hinting only works for objects and arrays. You can’t offer
hints for types such as integers, floats, or strings.
Constructors and Destructors
Often, you’ll want to execute a number of tasks when creating and destroying objects.
For example, you might want to immediately assign several fields of a newly instanti-
ated object. However, if you have to do so manually, you’ll almost certainly forget to
execute all of the required tasks. Object-oriented programming goes a long way toward
removing the possibility for such errors by offering special methods, called construc-
tors and destructors, that automate the object creation and destruction processes.
Constructors
You often want to initialize certain fields and even trigger the execution of methods
found when an object is newly instantiated. There’s nothing wrong with doing so
immediately after instantiation, but it would be easier if this were done for you auto-
matically. Such a mechanism exists in OOP, known as a constructor. Quite simply, a
constructor is defined as a block of code that automatically executes at the time of
object instantiation. OOP constructors offer a number of advantages:
• Constructors can accept parameters, which are assigned to specific object
fields at creation time.
• Constructors can call class methods or other functions.
• Class constructors can call on other constructors, including those from the
class parent.
This section reviews how all of these advantages work with PHP 5’s improved
constructor functionality.


Gilmore_862-8C06.fm Page 182 Tuesday, February 12, 2008 9:12 AM
CHAPTER 6 ■ OBJECT-ORIENTED PHP
183
■Note PHP 4 also offered class constructors, but it used a different more cumbersome syntax than
that used in version 5. Version 4 constructors were simply class methods of the same name as the class
they represented. Such a convention made it tedious to rename a class. The new constructor-naming
convention resolves these issues. For reasons of compatibility, however, if a class is found to not contain
a constructor satisfying the new naming convention, that class will then be searched for a method
bearing the same name as the class; if located, this method is considered the constructor.
PHP recognizes constructors by the name __construct. The general syntax for
constructor declaration follows:
function __construct([argument1, argument2, , argumentN])
{
// Class initialization code
}
As an example, suppose you want to immediately populate certain book fields with
information specific to a supplied ISBN. For example, you might want to know the
title and author of a book, in addition to how many copies the library owns and how
many are presently available for loan. This code might look like this:
<?php
class Book
{
private $title;
private $isbn;
private $copies;
public function _construct($isbn)
{
$this->setIsbn($isbn);
$this->getTitle();
$this->getNumberCopies();

}
public function setIsbn($isbn)
{
$this->isbn = $isbn;
}
Gilmore_862-8C06.fm Page 183 Tuesday, February 12, 2008 9:12 AM
184
CHAPTER 6
■ OBJECT-ORIENTED PHP
public function getTitle() {
$this->title = "Beginning Python";
print "Title: ".$this->title."<br />";
}
public function getNumberCopies() {
$this->copies = "5";
print "Number copies available: ".$this->copies."<br />";
}
}
$book = new book("159059519X");
?>
This results in the following:
Title: Beginning Python
Number copies available: 5
Of course, a real-life implementation would likely involve somewhat more intelligent
get methods (e.g., methods that query a database), but the point is made. Instantiating
the book object results in the automatic invocation of the constructor, which in turn
calls the setIsbn(), getTitle(), and getNumberCopies() methods. If you know that
such methods should be called whenever a new object is instantiated, you’re far better
off automating the calls via the constructor than attempting to manually call them
yourself.

Additionally, if you would like to make sure that these methods are called only via the
constructor, you should set their scope to private, ensuring that they cannot be
directly called by the object or by a subclass.
Invoking Parent Constructors
PHP does not automatically call the parent constructor; you must call it explicitly
using the parent keyword. An example follows:
Gilmore_862-8C06.fm Page 184 Tuesday, February 12, 2008 9:12 AM
CHAPTER 6 ■ OBJECT-ORIENTED PHP
185
<?php
class Employee
{
protected $name;
protected $title;
function __construct()
{
echo "<p>Staff constructor called!</p>";
}
}
class Manager extends Employee
{
function __construct()
{
parent::__construct();
echo "<p>Manager constructor called!</p>";
}
}
$employee = new Manager();
?>
This results in the following:

Employee constructor called!
Manager constructor called!
Neglecting to include the call to parent::__construct() results in the invocation of
only the Manager constructor, like this:
Manager constructor called!
Gilmore_862-8C06.fm Page 185 Tuesday, February 12, 2008 9:12 AM
186
CHAPTER 6
■ OBJECT-ORIENTED PHP
Invoking Unrelated Constructors
You can invoke class constructors that don’t have any relation to the instantiated
object simply by prefacing __constructor with the class name, like so:
classname::__construct()
As an example, assume that the Manager and Employee classes used in the previous
example bear no hierarchical relationship; instead, they are simply two classes located
within the same library. The Employee constructor could still be invoked within Manager’s
constructor, like this:
Employee::__construct()
Calling the Employee constructor like this results in the same outcome as that shown in
the example.
■Note You may be wondering why the extremely useful constructor-overloading feature, available in
many OOP languages, has not been discussed. The answer is simple: PHP does not support this feature.
Destructors
Although objects were automatically destroyed upon script completion in PHP 4, it
wasn’t possible to customize this cleanup process. With the introduction of destruc-
tors in PHP 5, this constraint is no more. Destructors are created like any other method
but must be titled __destruct(). An example follows:
<?php
class Book
{

private $title;
private $isbn;
private $copies;
function __construct($isbn)
{
echo "<p>Book class instance created.</p>";
}
Gilmore_862-8C06.fm Page 186 Tuesday, February 12, 2008 9:12 AM
CHAPTER 6 ■ OBJECT-ORIENTED PHP
187
function __destruct()
{
echo "<p>Book class instance destroyed.</p>";
}
}
$book = new Book("1893115852");
?>
Here’s the result:
Book class instance created.
Book class instance destroyed.
When the script is complete, PHP will destroy any objects that reside in memory.
Therefore, if the instantiated class and any information created as a result of the
instantiation reside in memory, you’re not required to explicitly declare a destructor.
However, if less volatile data is created (say, stored in a database) as a result of the
instantiation and should be destroyed at the time of object destruction, you’ll need to
create a custom destructor.
Static Class Members
Sometimes it’s useful to create fields and methods that are not invoked by any particular
object but rather are pertinent to and are shared by all class instances. For example,
suppose that you are writing a class that tracks the number of Web page visitors. You

wouldn’t want the visitor count to reset to zero every time the class is instantiated, and
therefore you would set the field to be of the static scope:
<?php
class Visitor
{
private static $visitors = 0;
Gilmore_862-8C06.fm Page 187 Tuesday, February 12, 2008 9:12 AM
188
CHAPTER 6
■ OBJECT-ORIENTED PHP
function __construct()
{
self::$visitors++;
}
static function getVisitors()
{
return self::$visitors;
}
}
/* Instantiate the Visitor class. */
$visits = new Visitor();
echo Visitor::getVisitors()."<br />";
/* Instantiate another Visitor class. */
$visits2 = new Visitor();
echo Visitor::getVisitors()."<br />";
?>
The results are as follows:
1
2
Because the $visitors field was declared as static, any changes made to its value

(in this case via the class constructor) are reflected across all instantiated objects.
Also note that static fields and methods are referred to using the self keyword and
class name, rather than via $this and arrow operators. This is because referring to
static fields using the means allowed for their “regular” siblings is not possible and will
result in a syntax error if attempted.
■Note You can’t use $this within a class to refer to a field declared as static.
Gilmore_862-8C06.fm Page 188 Tuesday, February 12, 2008 9:12 AM
CHAPTER 6 ■ OBJECT-ORIENTED PHP
189
The instanceof Keyword
The instanceof keyword was introduced with PHP 5. With it you can determine whether
an object is an instance of a class, is a subclass of a class, or implements a particular
interface, and do something accordingly. For example, suppose you want to learn
whether an object called manager is derived from the class Employee:
$manager = new Employee();

if ($manager instanceof Employee) echo "Yes";
There are two points worth noting here. First, the class name is not surrounded by
any sort of delimiters (quotes). Including them will result in a syntax error. Second,
if this comparison fails, the script will abort execution. The instanceof keyword is
particularly useful when you’re working with a number of objects simultaneously.
For example, you might be repeatedly calling a particular function but want to tweak
that function’s behavior in accordance with a given type of object. You might use a
case statement and the instanceof keyword to manage behavior in this fashion.
Helper Functions
A number of functions are available to help the developer manage and use class
libraries. These functions are introduced in this section.
Determining Whether a Class Exists
The class_exists() function returns TRUE if the class specified by class_name exists
within the currently executing script context, and returns FALSE otherwise. Its proto-

type follows:
boolean class_exists(string class_name)
Determining Object Context
The get_class() function returns the name of the class to which object belongs and
returns FALSE if object is not an object. Its prototype follows:
string get_class(object object)
Gilmore_862-8C06.fm Page 189 Tuesday, February 12, 2008 9:12 AM
190
CHAPTER 6
■ OBJECT-ORIENTED PHP
Learning About Class Methods
The get_class_methods() function returns an array containing all method names
defined by the class class_name. Its prototype follows:
array get_class_methods(mixed class_name)
Learning About Class Fields
The get_class_vars() function returns an associative array containing the names
of all fields and their corresponding values defined within the class specified by
class_name. Its prototype follows:
array get_class_vars(string class_name)
Learning About Declared Classes
The function get_declared_classes() returns an array containing the names of all
classes defined within the currently executing script. The output of this function will
vary according to how your PHP distribution is configured. For instance, executing
get_declared_classes() on a test server produces a list of 97 classes. Its prototype
follows:
array get_declared_classes(void)
Learning About Object Fields
The function get_object_vars() returns an associative array containing the defined
fields available to object and their corresponding values. Those fields that don’t possess
a value will be assigned NULL within the associative array. Its prototype follows:

array get_object_vars(object object)
Determining an Object’s Parent Class
The get_parent_class() function returns the name of the parent of the class to which
object belongs. If object’s class is a base class, that class name will be returned. Its
prototype follows:
string get_parent_class(mixed object)
Gilmore_862-8C06.fm Page 190 Tuesday, February 12, 2008 9:12 AM
CHAPTER 6 ■ OBJECT-ORIENTED PHP
191
Determining Interface Existence
The interface_exists() function determines whether an interface exists, returning
TRUE if it does, and FALSE otherwise. Its prototype follows:
boolean interface_exists(string interface_name [, boolean autoload])
Determining Object Type
The is_a() function returns TRUE if object belongs to a class of type class_name or if
it belongs to a class that is a child of class_name. If object bears no relation to the
class_name type, FALSE is returned. Its prototype follows:
boolean is_a(object object, string class_name)
Determining Object Subclass Type
The is_subclass_of() function returns TRUE if object belongs to a class inherited
from class_name, and returns FALSE otherwise. Its prototype follows:
boolean is_subclass_of(object object, string class_name)
Determining Method Existence
The method_exists() function returns TRUE if a method named method_name is available to
object, and returns FALSE otherwise. Its prototype follows:
boolean method_exists(object object, string method_name)
Autoloading Objects
For organizational reasons, it’s common practice to place each class in a separate file.
Returning to the library scenario, suppose the management application calls for classes
representing books, employees, events, and patrons. Tasked with this project, you might

create a directory named classes and place the following files in it: Books.class.php,
Employees.class.php, Events.class.php, and Patrons.class.php. While this does
indeed facilitate class management, it also requires that each separate file be made
available to any script requiring it, typically through the require_once() statement.
Therefore, a script requiring all four classes would require that the following state-
ments be inserted at the beginning:
Gilmore_862-8C06.fm Page 191 Tuesday, February 12, 2008 9:12 AM
192
CHAPTER 6
■ OBJECT-ORIENTED PHP
require_once("classes/Books.class.php");
require_once("classes/Employees.class.php");
require_once("classes/Events.class.php");
require_once("classes/Patrons.class.php");
Managing class inclusion in this manner can become rather tedious and adds an
extra step to the already often complicated development process. To eliminate this
additional task, the concept of autoloading objects was introduced in PHP 5. Autoloading
allows you to define a special __autoload function that is automatically called when-
ever a class is referenced that hasn’t yet been defined in the script. You can eliminate
the need to manually include each class file by defining the following function:
function __autoload($class) {
require_once("classes/$class.class.php");
}
Defining this function eliminates the need for the require_once() statements because
when a class is invoked for the first time, __autoload() will be called, loading the class
according to the commands defined in __autoload(). This function can be placed in
a global application configuration file, meaning only that function will need to be
made available to the script.
■Note The require_once() function and its siblings were introduced in Chapter 3.
Summary

This chapter introduced object-oriented programming fundamentals, followed by an
overview of PHP’s basic object-oriented features, devoting special attention to those
enhancements and additions that were made available with the PHP 5 release.
The next chapter expands upon this introductory information, covering topics such as
inheritance, interfaces, abstract classes, and more.
Gilmore_862-8C06.fm Page 192 Tuesday, February 12, 2008 9:12 AM
193
■ ■ ■
CHAPTER 7
Advanced OOP Features
Chapter 6 introduced the fundamentals of object-oriented programming (OOP).
This chapter builds on that foundation by introducing several of the more advanced
OOP features that you should consider once you have mastered the basics. Specifi-
cally, this chapter introduces the following four features:
Object cloning: One of the major improvements to PHP’s object-oriented model
in version 5 is the treatment of all objects as references rather than values. However,
how do you go about creating a copy of an object if all objects are treated as refer-
ences? By cloning the object.
Inheritance: As discussed in Chapter 6, the ability to build class hierarchies through
inheritance is a key concept of OOP. This chapter introduces PHP’s inheritance
features and syntax, and it includes several examples that demonstrate this key
OOP feature.
Interfaces: An interface is a collection of unimplemented method definitions and
constants that serves as a class blueprint. Interfaces define exactly what can be
done with the class, without getting bogged down in implementation-specific
details. This chapter introduces PHP’s interface support and offers several exam-
ples demonstrating this powerful OOP feature.
Abstract classes: An abstract class is a class that cannot be instantiated. Abstract
classes are intended to be inherited by a class that can be instantiated, better known
as a concrete class. Abstract classes can be fully implemented, partially implemented,

or not implemented at all. This chapter presents general concepts surrounding
abstract classes, coupled with an introduction to PHP’s class abstraction capabilities.
Namespaces: Namespaces help you to more effectively manage your code base
by compartmentalizing various libraries and classes according to context. In this
chapter I’ll introduce you to PHP 6’s new namespace feature.
Gilmore_862-8C07.fm Page 193 Tuesday, February 12, 2008 9:13 AM
194
CHAPTER 7
■ ADVANCED OOP FEATURES
■Note All the features described in this chapter are available only for PHP 5 and above.
Advanced OOP Features Not Supported by PHP
If you have experience in other object-oriented languages, you might be scratching
your head over why the previous list of features doesn’t include one or more partic-
ular OOP features that you are familiar with from other languages. The reason might
well be that PHP doesn’t support those features. To save you from further head
scratching, the following list enumerates the advanced OOP features that are not
supported by PHP and thus are not covered in this chapter:
Method overloading: The ability to implement polymorphism through functional
overloading is not supported by PHP and probably never will be.
Operator overloading: The ability to assign additional meanings to operators based
upon the type of data you’re attempting to modify did not make the cut this time
around. Based on discussions found in the PHP developer’s mailing list, it is unlikely
that this feature will ever be implemented.
Multiple inheritance: PHP does not support multiple inheritance. Implementa-
tion of multiple interfaces is supported, however.
Only time will tell whether any or all of these features will be supported in future
versions of PHP.
Object Cloning
One of the biggest drawbacks to PHP 4’s object-oriented capabilities is its treatment
of objects as just another datatype, which impeded the use of many common OOP

methodologies, such as design patterns. Such methodologies depend on the ability to
pass objects to other class methods as references, rather than as values, which is no
longer PHP’s default practice. Thankfully, this matter has been resolved with PHP 5,
and now all objects are treated by default as references. However, because all objects
are treated as references rather than as values, it is now more difficult to copy an
object. If you try to copy a referenced object, it will simply point back to the addressing
location of the original object. To remedy the problems with copying, PHP offers an
explicit means for cloning an object.
Gilmore_862-8C07.fm Page 194 Tuesday, February 12, 2008 9:13 AM
CHAPTER 7 ■ ADVANCED OOP FEATURES
195
Cloning Example
You clone an object by prefacing it with the clone keyword, like so:
destinationObject = clone targetObject;
Listing 7-1 presents an object-cloning example. This example uses a sample class
named Corporate_Drone, which contains two members (employeeid and tiecolor) and
corresponding getters and setters for these members. The example code instantiates a
Corporate_Drone object and uses it as the basis for demonstrating the effects of a
clone operation.
Listing 7-1. Cloning an Object with the clone Keyword
<?php
class Corporate_Drone {
private $employeeid;
private $tiecolor;
// Define a setter and getter for $employeeid
function setEmployeeID($employeeid) {
$this->employeeid = $employeeid;
}
function getEmployeeID() {
return $this->employeeid;

}
// Define a setter and getter for $tiecolor
function setTieColor($tiecolor) {
$this->tiecolor = $tiecolor;
}
function getTieColor() {
return $this->tiecolor;
}
}
// Create new Corporate_Drone object
$drone1 = new Corporate_Drone();
Gilmore_862-8C07.fm Page 195 Tuesday, February 12, 2008 9:13 AM
196
CHAPTER 7
■ ADVANCED OOP FEATURES
// Set the $drone1 employeeid member
$drone1->setEmployeeID("12345");
// Set the $drone1 tiecolor member
$drone1->setTieColor("red");
// Clone the $drone1 object
$drone2 = clone $drone1;
// Set the $drone2 employeeid member
$drone2->setEmployeeID("67890");
// Output the $drone1 and $drone2 employeeid members
printf("drone1 employeeID: %d <br />", $drone1->getEmployeeID());
printf("drone1 tie color: %s <br />", $drone1->getTieColor());
printf("drone2 employeeID: %d <br />", $drone2->getEmployeeID());
printf("drone2 tie color: %s <br />", $drone2->getTieColor());
?>
Executing this code returns the following output:

drone1 employeeID: 12345
drone1 tie color: red
drone2 employeeID: 67890
drone2 tie color: red
As you can see, $drone2 became an object of type Corporate_Drone and inherited
the member values of $drone1. To further demonstrate that $drone2 is indeed of type
Corporate_Drone, its employeeid member was also reassigned.
The __clone() Method
You can tweak an object’s cloning behavior by defining a __clone() method within
the object class. Any code in this method will execute during the cloning operation.
Gilmore_862-8C07.fm Page 196 Tuesday, February 12, 2008 9:13 AM
CHAPTER 7 ■ ADVANCED OOP FEATURES
197
This occurs in addition to the copying of all existing object members to the target
object. Now the Corporate_Drone class is revised, adding the following method:
function __clone() {
$this->tiecolor = "blue";
}
With this in place, let’s create a new Corporate_Drone object, add the employeeid
member value, clone it, and then output some data to show that the cloned object’s
tiecolor was indeed set through the __clone() method. Listing 7-2 offers the example.
Listing 7-2. Extending clone’s Capabilities with the __clone() Method
// Create new Corporate_Drone object
$drone1 = new Corporate_Drone();
// Set the $drone1 employeeid member
$drone1->setEmployeeID("12345");
// Clone the $drone1 object
$drone2 = clone $drone1;
// Set the $drone2 employeeid member
$drone2->setEmployeeID("67890");

// Output the $drone1 and $drone2 employeeid members
printf("drone1 employeeID: %d <br />", $drone1->getEmployeeID());
printf("drone2 employeeID: %d <br />", $drone2->getEmployeeID());
printf("drone2 tie color: %s <br />", $drone2->getTieColor());
Executing this code returns the following output:
drone1 employeeID: 12345
drone2 employeeID: 67890
drone2 tie color: blue
Gilmore_862-8C07.fm Page 197 Tuesday, February 12, 2008 9:13 AM
198
CHAPTER 7
■ ADVANCED OOP FEATURES
Inheritance
People are quite adept at thinking in terms of organizational hierarchies; thus, it
doesn’t come as a surprise that we make widespread use of this conceptual view to
manage many aspects of our everyday lives. Corporate management structures, the
U.S. tax system, and our view of the plant and animal kingdoms are just a few exam-
ples of the systems that rely heavily on hierarchical concepts. Because OOP is based
on the premise of allowing humans to closely model the properties and behaviors of
the real-world environment we’re trying to implement in code, it makes sense to also
be able to represent these hierarchical relationships.
For example, suppose that your application calls for a class titled Employee, which
is intended to represent the characteristics and behaviors that one might expect from
an employee. Some class members that represent characteristics might include the
following:
• name: The employee’s name
• age: The employee’s age
• salary: The employee’s salary
• yearsEmployed: The number of years the employee has been with the company
Some Employee class methods might include the following:

• doWork: Perform some work-related task
• eatLunch: Take a lunch break
• takeVacation: Make the most of those valuable two weeks
These characteristics and behaviors would be relevant to all types of employees,
regardless of the employee’s purpose or stature within the organization. Obviously,
though, there are also differences among employees; for example, the executive might
hold stock options and be able to pillage the company, while other employees are not
afforded such luxuries. An assistant must be able to take a memo, and an office manager
needs to take supply inventories. Despite these differences, it would be quite ineffi-
cient if you had to create and maintain redundant class structures for those attributes
that all classes share. The OOP development paradigm takes this into account, allowing
you to inherit from and build upon existing classes.
Gilmore_862-8C07.fm Page 198 Tuesday, February 12, 2008 9:13 AM
CHAPTER 7 ■ ADVANCED OOP FEATURES
199
Class Inheritance
As applied to PHP, class inheritance is accomplished by using the extends keyword.
Listing 7-3 demonstrates this ability, first creating an Employee class and then creating
an Executive class that inherits from Employee.
■Note A class that inherits from another class is known as a child class, or a subclass. The class from
which the child class inherits is known as the parent, or base class.
Listing 7-3. Inheriting from a Base Class
<?php
// Define a base Employee class
class Employee {
private $name;
// Define a setter for the private $name member.
function setName($name) {
if ($name == "") echo "Name cannot be blank!";
else $this->name = $name;

}
// Define a getter for the private $name member
function getName() {
return "My name is ".$this->name."<br />";
}
} // end Employee class
// Define an Executive class that inherits from Employee
class Executive extends Employee {
// Define a method unique to Employee
function pillageCompany() {
echo "I'm selling company assets to finance my yacht!";
}
Gilmore_862-8C07.fm Page 199 Tuesday, February 12, 2008 9:13 AM
200
CHAPTER 7
■ ADVANCED OOP FEATURES
} // end Executive class
// Create a new Executive object
$exec = new Executive();
// Call the setName() method, defined in the Employee class
$exec->setName("Richard");
// Call the getName() method
echo $exec->getName();
// Call the pillageCompany() method
$exec->pillageCompany();
?>
This returns the following:
My name is Richard.
I'm selling company assets to finance my yacht!
Because all employees have a name, the Executive class inherits from the Employee

class, saving you the hassle of having to re-create the name member and the corre-
sponding getter and setter. You can then focus solely on those characteristics that
are specific to an executive, in this case a method named pillageCompany(). This
method is available solely to objects of type Executive, and not to the Employee class
or any other class, unless of course you create a class that inherits from Executive.
The following example demonstrates that concept, producing a class titled CEO,
which inherits from Executive:
<?php
class Employee {

}
class Executive extends Employee {

}
Gilmore_862-8C07.fm Page 200 Tuesday, February 12, 2008 9:13 AM
CHAPTER 7 ■ ADVANCED OOP FEATURES
201
class CEO extends Executive {
function getFacelift() {
echo "nip nip tuck tuck";
}
}
$ceo = new CEO();
$ceo->setName("Bernie");
$ceo->pillageCompany();
$ceo->getFacelift();
?>
Because Executive has inherited from Employee, objects of type CEO also have
all the members and methods that are available to Executive, in addition to the
getFacelift() method, which is reserved solely for objects of type CEO.

Inheritance and Constructors
A common question pertinent to class inheritance has to do with the use of construc-
tors. Does a parent class constructor execute when a child is instantiated? If so, what
happens if the child class also has its own constructor? Does it execute in addition to
the parent constructor, or does it override the parent? Such questions are answered
in this section.
If a parent class offers a constructor, it does execute when the child class is instanti-
ated, provided that the child class does not also have a constructor. For example,
suppose that the Employee class offers this constructor:
function __construct($name) {
$this->setName($name);
}
Then you instantiate the CEO class and retrieve the name member:
$ceo = new CEO("Dennis");
echo $ceo->getName();
It will yield the following:
My name is Dennis
Gilmore_862-8C07.fm Page 201 Tuesday, February 12, 2008 9:13 AM
202
CHAPTER 7
■ ADVANCED OOP FEATURES
However, if the child class also has a constructor, that constructor will execute
when the child class is instantiated, regardless of whether the parent class also has a
constructor. For example, suppose that in addition to the Employee class containing
the previously described constructor, the CEO class contains this constructor:
function __construct() {
echo "<p>CEO object created!</p>";
}
Then you instantiate the CEO class:
$ceo = new CEO("Dennis");

echo $ceo->getName();
This time it will yield the following output because the CEO constructor overrides
the Employee constructor:
CEO object created!
My name is
When it comes time to retrieve the name member, you find that it’s blank because
the setName() method, which executes in the Employee constructor, never fires. Of
course, you’re quite likely going to want those parent constructors to also fire. Not to
fear because there is a simple solution. Modify the CEO constructor like so:
function __construct($name) {
parent::__construct($name);
echo "<p>CEO object created!</p>";
}
Again instantiating the CEO class and executing getName() in the same fashion as
before, this time you’ll see a different outcome:
CEO object created!
My name is Dennis
Gilmore_862-8C07.fm Page 202 Tuesday, February 12, 2008 9:13 AM
CHAPTER 7 ■ ADVANCED OOP FEATURES
203
You should understand that when parent::__construct() was encountered, PHP
began a search upward through the parent classes for an appropriate constructor.
Because it did not find one in Executive, it continued the search up to the Employee
class, at which point it located an appropriate constructor. If PHP had located a
constructor in the Employee class, then it would have fired. If you want both the Employee
and Executive constructors to fire, you need to place a call to parent::__construct() in
the Executive constructor.
You also have the option to reference parent constructors in another fashion. For
example, suppose that both the Employee and Executive constructors should execute
when a new CEO object is created. As mentioned in the last chapter, these construc-

tors can be referenced explicitly within the CEO constructor like so:
function __construct($name) {
Employee::__construct($name);
Executive::__construct();
echo "<p>CEO object created!</p>";
}
Interfaces
An interface defines a general specification for implementing a particular service,
declaring the required functions and constants without specifying exactly how it
must be implemented. Implementation details aren’t provided because different
entities might need to implement the published method definitions in different
ways. The point is to establish a general set of guidelines that must be implemented
in order for the interface to be considered implemented.
■Caution Class members are not defined within interfaces. This is a matter left entirely to the imple-
menting class.
Take for example the concept of pillaging a company. This task might be accom-
plished in a variety of ways, depending on who is doing the dirty work. For example,
a typical employee might do his part by using the office credit card to purchase shoes
and movie tickets, writing the purchases off as “office expenses,” while an executive
might force his assistant to reallocate funds to his Swiss bank account through the
online accounting system. Both employees are intent on accomplishing the task, but
Gilmore_862-8C07.fm Page 203 Tuesday, February 12, 2008 9:13 AM
204
CHAPTER 7
■ ADVANCED OOP FEATURES
each goes about it in a different way. In this case, the goal of the interface is to define
a set of guidelines for pillaging the company and then ask the respective classes to
implement that interface accordingly. For example, the interface might consist of just
two methods:
emptyBankAccount()

burnDocuments()
You can then ask the Employee and Executive classes to implement these features. In
this section, you’ll learn how this is accomplished. First, however, take a moment to
understand how PHP 5 implements interfaces. In PHP, an interface is created like so:
interface IinterfaceName
{
CONST 1;

CONST N;
function methodName1();

function methodNameN();
}
■Tip It’s common practice to preface the names of interfaces with the letter I to make them easier
to recognize.
The contract is completed when a class implements the interface via the implements
keyword. All methods must be implemented, or the implementing class must be
declared abstract (a concept introduced in the next section); otherwise, an error
similar to the following will occur:
Fatal error: Class Executive contains 1 abstract methods and must
therefore be declared abstract (pillageCompany::emptyBankAccount) in
/www/htdocs/pmnp/7/executive.php on line 30
The following is the general syntax for implementing the preceding interface:
Gilmore_862-8C07.fm Page 204 Tuesday, February 12, 2008 9:13 AM
CHAPTER 7 ■ ADVANCED OOP FEATURES
205
class Class_Name implements interfaceName
{
function methodName1()
{

// methodName1() implementation
}
function methodNameN()
{
// methodName1() implementation
}
}
Implementing a Single Interface
This section presents a working example of PHP’s interface implementation by creating
and implementing an interface, named IPillage, that is used to pillage the company:
interface IPillage
{
function emptyBankAccount();
function burnDocuments();
}
This interface is then implemented for use by the Executive class:
class Executive extends Employee implements IPillage
{
private $totalStockOptions;
function emptyBankAccount()
{
echo "Call CFO and ask to transfer funds to Swiss bank account.";
}
function burnDocuments()
{
echo "Torch the office suite.";
}
}
Gilmore_862-8C07.fm Page 205 Tuesday, February 12, 2008 9:13 AM

×