The object name is used in the same way as an object’s attributes as follows: $a->operation1; $a->operation212, “test”; If our operations return something, we can capture that return dat
Trang 1We then call operations the same way that we call other functions: by using their name and
placing any parameters that they need in brackets Because these operations belong to an
object rather than normal functions, we need to specify to which object they belong The
object name is used in the same way as an object’s attributes as follows:
$a->operation1();
$a->operation2(12, “test”);
If our operations return something, we can capture that return data as follows:
$x = $a->operation1();
$y = $a->operation2(12, “test”);
Implementing Inheritance in PHP
If our class is to be a subclass of another, you can use the extendskeyword to specify this
The following code creates a class named Bthat inherits from some previously defined class
named A
class B extends A
{
var $attribute2;
function operation2()
{
}
}
If the class Awas declared as follows:
class A
{
var $attribute1;
function operation1()
{
}
}
all the following accesses to operations and attributes of an object of type Bwould be valid:
$b = new B();
$b->operation1();
$b->attribute1 = 10;
$b->operation2();
$b->attribute2 = 10;
Note that because class Bextends class A, we can refer to operation1()and $attribute1,
although these were declared in class A As a subclass of A,Bhas all the same functionality and
data In addition,Bhas declared an attribute and an operation of its own
6
Trang 2It is important to note that inheritance only works in one direction The subclass or child inher-its features from inher-its parent or superclass, but the parent does not take on features of the child This means that the last two lines in this code are wrong:
$a = new A();
$a->operation1();
$a->attribute1 = 10;
$a->operation2();
$a->attribute2 = 10;
The class A does not have an operation2()or an attribute2
Overriding
We have shown a subclass declaring new attributes and operations It is also valid and some-times useful to redeclare the same attributes and operations We might do this to give an attribute in the subclass a different default value to the same attribute in its superclass, or to give an operation in the subclass different functionality to the same operation in its superclass
This is called overriding.
For instance, if we have a class A: class A
{ var $attribute = “default value”;
function operation() {
echo “Something<br>”;
echo “The value of \$attribute is $this->attribute<br>”;
} } and want to alter the default value of $attributeand provide new functionality for opera-tion(), we can create the following class B, which overrides $attributeand operation(): class B extends A
{ var $attribute = “different value”;
function operation() {
echo “Something else<br>”;
echo “The value of \$attribute is $this->attribute<br>”;
} }
Trang 3Declaring Bdoes not affect the original definition of A Consider the following two lines of
code:
$a = new A();
$a -> operation();
We have created an object of type Aand called its operation()function This will produce
Something
The value of $attribute is default value
proving that creating Bhas not altered A If we create an object of type B, we will get different
output
This code
$b = new B();
$b -> operation();
will produce
Something else
The value of $attribute is different value
In the same way that providing new attributes or operations in a subclass does not affect the
superclass, overriding attributes or operations in a subclass does not affect the superclass
A subclass will inherit all the attributes and operations of its superclass, unless you provide
replacements If you provide a replacement definition, this takes precedence and overrides the
original definition
Unlike some other OO languages, PHP does not allow you to override a function and still be
able to call the version defined in the parent
Inheritance can be many layers deep We can declare a class imaginatively called C, that
extends Band therefore inherits features from Band from B’s parent A The class Ccan again
choose which attributes and operations from its parents to override and replace
Multiple Inheritance
Some OO languages support multiple inheritance, but PHP does not This means that each
class can only inherit from one parent No restrictions exist for how many children can share a
single parent
It might not seem immediately clear what this means Figure 6.1 shows three different ways
that three classes named A,B, and Ccan inherit
6
Trang 4F IGURE 6.1
PHP does not support multiple inheritance.
The leftcombination shows class Cinheriting from class B, which in turn inherits from class
A Each class has at most one parent, so this is a perfectly valid single inheritance in PHP The centercombination shows class Band Cinheriting from class A Each class has at most one parent, so again this is a valid single inheritance
Therightcombination shows class Cinheriting from both class Aand class B In this case, class Chas two parents, so this is multiple inheritance and is invalid in PHP
Designing Classes
Now that you know some of the concepts behind objects and classes and the syntax to imple-ment them in PHP, it is time to look at how to design useful classes
Many classes in your code will represent classes or categories of real-world objects Classes you might use in Web development might include pages, user interface components, shopping carts, error handling, product categories, or customers
Objects in your code can also represent specific instances of the previously mentioned classes, for example, the home page, a particular button, or the shopping cart in use by Fred Smith at a particular time Fred Smith himself can be represented by an object of type customer Each item that Fred purchases can be represented as an object, belonging to a category or class
In the previous chapter, we used simple include files to give our fictional company, TLA Consulting, a consistent look and feel across the different pages of their Web site Using classes and the timesaving power of inheritance, we can create a more advanced version of the same site
We want to be able to quickly create pages for TLA that look and behave in the same way Those pages should be able to be modified to suit the different parts of the site
A
B
C Single Inheritance
A
Single Inheritance
C
Multiple Inheritance
Trang 5We are going to create a Pageclass The main goal of this class is to limit the amount of
HTML needed to create a new page It should allow us to alter the parts that change from page
to page, while automatically generating the elements that stay the same
The class should provide a flexible framework for creating new pages and should not
compro-mise our freedom
Because we are generating our page from a script rather than with static HTML, we can add
any number of clever things including functionality to enable the following:
• Enable us to only alter page elements in one place If we change the copyright notice or add an extra button, we should only need to make the change in a single place
• Have default content for most parts of the page, but be able to modify each element where required, setting custom values for elements such as the title and metatags
• Recognize which page is being viewed and alter navigation elements to suit—there is no point in having a button that takes you to the home page located on the home page
• Allow us to replace standard elements for particular pages If for instance, we want dif-ferent navigation buttons in sections of the site, we should be able to replace the standard ones
Writing the Code for Your Class
Having decided what we want the output from our code to look like, and a few features we
would like for it, how do we implement it?
We will talk later in the book about design and project management for large projects For
now, we will concentrate on the parts specific to writing object-oriented PHP
Our class will need a logical name Because it represents a page, it will be called Page To
declare a class called Page, we type
class Page
{
}
Our class needs some attributes We will set elements that we might want changed from page
to page as attributes of our class The main contents of the page, which will be a combination
of HTML tags and text, will be called $content We can declare the content with the following
line of code within the class definition:
var $content;
6
Trang 6We can also set attributes to store the page’s title We will probably want to change this to clearly show what particular page our visitor is looking at Rather than have blank titles, we will provide a default title with the following declaration:
var $title = “TLA Consulting Pty Ltd”;
Most commercial Web pages include metatags to help search engines index them In order to
be useful, metatags should probably change from page to page Again, we will provide a default value:
var $keywords = “TLA Consulting, Three Letter Abbreviation,
some of my best friends are search engines”;
The navigation buttons shown on the original page in Figure 5.2 (see the previous chapter) should probably be kept the same from page to page to avoid confusing people, but in order to change them easily, we will make them an attribute too Because there might be a variable number of buttons, we will use an array, and store both the text for the button and the URL it should point to
var $buttons = array( “Home” => “home.php”,
“Contact” => “contact.php”,
“Services” => “services.php”,
“site Map” => “map.php”
);
In order to provide some functionality, our class will also need operations We can start by pro-viding accessor functions to set and get the values of the attributes we defined These all take a form like this:
function SetContent($newcontent) {
$this->content = $newcontent;
} Because it is unlikely that we will be requesting any of these values from outside the class, we have elected not to provide a matching collection of GETfunctions
The main purpose of this class is to display a page of HTML, so we will need a function We have called ours Display(), and it is as follows:
function Display() {
echo “<html>\n<head>\n”;
$this -> DisplayTitle();
$this -> DisplayKeywords();
$this -> DisplayStyles();
echo “</head>\n<body>\n”;
Trang 7$this -> DisplayHeader();
$this -> DisplayMenu($this->buttons);
echo $this->content;
$this -> DisplayFooter();
echo “</body>\n</html>\n”;
}
The function includes a few simple echo statements to display HTML, but mainly consists of
calls to other functions in the class As you have probably guessed from their names, these
other functions display parts of the page
It is not compulsory to break functions up like this All these separate functions might simply
have been combined into one big function We separated them out for a number of reasons
Each function should have a defined task to perform The simpler this task is, the easier
writ-ing and testwrit-ing the function will be Don’t go too far—if you break your program up into too
many small units, it might be hard to read
Using inheritance, we can override operations We can replace one large Display() function,
but it is unlikely that we will want to change the way the entire page is displayed It will be
much better to break up the display functionality into a few self-contained tasks and be able to
override only the parts that we want to change
Our Display function calls DisplayTitle(),DisplayKeywords(), DisplayStyles(),
DisplayHeader(), DisplayMenu(), and DisplayFooter() This means that we need to define
these operations One of the improvements of PHP 4 over PHP 3 is that we can write
opera-tions or funcopera-tions in this logical order, calling the operation or function before the actual code
for the function In PHP 3 and many other languages, we need to write the function or
opera-tion before it can be called
Most of our operations are fairly simple and need to display some HTML and perhaps the
con-tents of our attributes
Listing 6.1 shows the complete class, which we have saved as page.incto include or require
into other files
L ISTING 6.1 page.inc—Our Page Class Provides an Easy Flexible Way to Create TLA Pages
<?
class Page
{
// class Page’s attributes
var $content;
var $title = “TLA Consulting Pty Ltd”;
6
Trang 8var $keywords = “TLA Consulting, Three Letter Abbreviation,
some of my best friends are search engines”; var $buttons = array( “Home” => “home.php”,
“Contact” => “contact.php”,
“Services” => “services.php”,
“Site Map” => “map.php”
);
// class Page’s operations function SetContent($newcontent) {
$this->content = $newcontent;
} function SetTitle($newtitle) {
$this->title = $newtitle;
} function SetKeywords($newkeywords) {
$this->keywords = $newkeywords;
} function SetButtons($newbuttons) {
$this->buttons = $newbuttons;
} function Display() {
echo “<html>\n<head>\n”;
$this -> DisplayTitle();
$this -> DisplayKeywords();
$this -> DisplayStyles();
echo “</head>\n<body>\n”;
$this -> DisplayHeader();
$this -> DisplayMenu($this->buttons);
echo $this->content;
$this -> DisplayFooter();
echo “</body>\n</html>\n”;
}
L ISTING 6.1 Continued
Trang 9function DisplayTitle()
{
echo “<title> $this->title </title>”;
}
function DisplayKeywords()
{
echo “<META name=\”keywords\” content=\”$this->keywords\”>”;
}
function DisplayStyles()
{
?>
<style>
h1 {color:white; font-size:24pt; text-align:center;
font-family:arial,sans-serif}
.menu {color:white; font-size:12pt; text-align:center;
font-family:arial,sans-serif; font-weight:bold}
td {background:black}
p {color:black; font-size:12pt; text-align:justify;
font-family:arial,sans-serif}
p.foot {color:white; font-size:9pt; text-align:center;
font-family:arial,sans-serif; font-weight:bold}
a:link,a:visited,a:active {color:white}
</style>
<?
}
function DisplayHeader()
{
?>
<table width=”100%” cellpadding = 12 cellspacing =0 border = 0>
<tr bgcolor = black>
<td align = left><img src = “logo.gif”></td>
<td>
<h1>TLA Consulting Pty Ltd</h1>
</td>
<td align = right><img src = “logo.gif”></td>
</tr>
</table>
<?
}
function DisplayMenu($buttons)
6
L ISTING 6.1 Continued
Trang 10{ echo “<table width = \”100%\” bgcolor = white”
.” cellpadding = 4 cellspacing = 4>\n”;
echo “ <tr>\n”;
//calculate button size
$width = 100/count($buttons);
while (list($name, $url) = each($buttons)) {
$this -> DisplayButton($width, $name, $url,
!$this->IsURLCurrentPage($url));
} echo “ </tr>\n”;
echo “</table>\n”;
} function IsURLCurrentPage($url) {
if(strpos( $GLOBALS[“SCRIPT_NAME”], $url )==false) {
return false;
} else { return true;
} } function DisplayButton($width, $name, $url, $active = true) {
if ($active) {
echo “<td width = \”$width%\”>
<a href = \”$url\”>
<img src = \”s-logo.gif\” alt = \”$name\” border = 0></a>
<a href = \”$url\”><span class=menu>$name</span></a></td>”; }
else { echo “<td width = \”$width%\”>
<img src = \”side-logo.gif\”>
<span class=menu>$name</span></td>”;
}
L ISTING 6.1 Continued