foreach $this->headers as $header Bringing It All Together Listing 8.5 includes the entire Table class, as well the code that instantiates a Table object and calls each of its methods
Trang 1foreach ( $this->headers as $header )
Bringing It All Together
Listing 8.5 includes the entire Table class, as well the code that instantiates a Table object and calls each of its methods
Listing 8.5: The Table Class
9: var $table_array = array();
10: var $headers = array();
Trang 4Figure 8.1: The Table object in action
The output looks neat as long as the individual strings are the same length This will change if we vary the length of any of the elements
Why a Class?
So, what's better about using an object to achieve this task than simply manipulating arrays ourselves as and when we need to? It certainly isn't efficiency We've added overheads to the process of storing and retrieving information
First, this code is reusable It has a clear purpose— to represent data in a certain way, and we can now slot it into any project that needs data stored and output in this way
Second, a Table object is active We can ask it to output its data without bothering
to write code to loop through its table_array property
Trang 5Third, we've built an interface to the object's functionality If we decide later to optimize the code in the class, we can do so without disturbing the rest of the project,
as long as the same methods remain, expecting the same arguments and returning the same data types
Finally, we can build classes that inherit, extend, and override its functionality This makes object-oriented code truly cool
Trang 6If that's not enough, there's even more magic to be found in Listing 8.6 Notice that
we didn't define a constructor method for the second_class class So, how was the name property changed from the default, "harry" to the value passed to the second_class class, "son of harry"? Because we didn't provide a constructor, the first_class class's constructor was automatically called
Note If a class extending another doesn't contain a constructor method, the
parent class's constructor method will be called automatically when a child object is created This feature is new in PHP4
Overriding the Method of a Parent Class
The second_class class currently creates objects that behave in exactly the same way as first_class objects In object-oriented code, child classes can override the methods of their parents, allowing objects instantiated from them to behave differently, while otherwise retaining much of the same functionality Listing 8.7 gives the second_class class its own sayHello() method
Listing 8.7: The Method of a Child Class Overriding That of Its Parent
1: <html>
Trang 832: </body>
33: </html>
The sayHello() method in the second_class class is called in preference to that in the parent class
Calling an Overridden Method
Occasionally, you will want the functionality of a parent class's method, as well as the benefit of your own additions Object-oriented programming allows you to have your cake and eat it too In Listing 8.8, the second_class's sayHello() method calls the method in the first_class class that it has overridden
Listing 8.8: Calling an Overridden Method
Trang 920: class second_class extends first_class
Defining HTMLTable's Properties
HTMLTable will format the data that it stores courtesy of Table's functionality using
a standard HTML table For this example, we will allow an HTMLTable's user to
Trang 10change the CELLPADDING argument of the TABLE element and the BGCOLOR argument of the TD element A real-world example should allow for many more changes than this
class HTMLTable extends Table
Creating the Constructor
You have already seen that a parent class's constructor is called automatically if you don't define a constructor for a child class In this case, however, we want to do more work with our constructor than has already been written for the Table class: function HTMLTable( $headers, $bg="#ffffff" )
to it Laziness is a virtue in programming, so we let the Table class's constructor do its thing and worry no more about it We initialize the HTMLObject's bgcolor property
Note If a child class is given a constructor method, the parent's constructor
is no longer called implicitly The child class's constructor must explicitly call that of its parent
Trang 11The setCellpadding() Method
A child class can of course create its own entirely new methods setCellpadding() allows a user to change the cellpadding property from the default Of course, it would be perfectly possible to set the cellpadding property directly from outside the object, but this is not good practice on the whole As a rule of thumb, it is best to create methods that will change properties on behalf of an object's user In a more complex version of this class, the setCellpadding() method might need to change other properties to reflect the change made to the cellpadding property Unfortunately, there is no neat way of enforcing privacy in PHP4
function setCellpadding( $padding )
{
$this->cellpadding = $padding;
}
The Output() Method
The Output() method completely overrides the equivalent method in the Table class
It outputs data according to exactly the same logic as its parent, adding HTML table formatting:
function output()
{
print "<table cellpadding=\"$this->cellpadding\" border=1>";
foreach ( $this->headers as $header )
Trang 12The Table and HTMLTable Classes in Their Entirety
Listing 8.9 brings the entire Table and HTMLTable examples together We also instantiate an HTMLTable object, change its cellpadding property, add some data, and call its ouptut() method In a real-world example, we would probably get our row data directly from a database
Listing 8.9: The Table and HTMLTable Classes
9: var $table_array = array();
10: var $headers = array();
Trang 1318: function addRow( $row )
Trang 1471: print "<table cellpadding=\"$this->cellpadding\" border=1>";
72: foreach ( $this->headers as $header )
73: print "<td bgcolor=\"$this->bgcolor\"><b>$header</b></td>"; 74: foreach ( $this->table_array as $row=>$cells )
75: {
76: print "<tr>";
77: foreach ( $cells as $cell )
Trang 15You can see the output from Listing 8.9 in Figure 8.2
Figure 8.2: The HTMLTable object in action
Why Use Inheritance?
So, why did we split Table from HTMLTable? Surely we could have saved ourselves time and space by building HTML table capabilities into the Table class? The answer lies in flexibility
Trang 16Imagine that a client gave you the brief to create a class that can maintain a table
of fields, organized in named columns If you had built a monolithic class that collected and stored the data, customized HTML, and output the result to the browser, all would seem to be well
If the same client came back to you and asked whether the code could be adapted additionally to write neatly formatted data to a text file, you could probably add some more methods and properties to make it do this too
A week or so later, the client realizes that she would like the code to be able to send data out as an email, and while you're at it, the company intranet uses a subset of XML; could this be accommodated too? At this stage, including all the functionality
in a single class is beginning to look a little unwieldy, and you would already be considering a complete rewrite of the code
Let's try this scenario out with our Table and HTMLTable examples We have already substantially separated formatting the data from acquiring and preparing it When our client asks that the code should be capable of outputting to a file, we only need
to create a new class that inherits from Table Let's call it FileTable We need make
no changes at all to our existing code The same would be true for MailTable and XMLTable Figure 8.3 illustrates the relationship between these classes
Figure 8.3: The relationship between the Table class and multiple child classes
What's more, we know that any object that inherits from Table will have an output()
method, so we can group a bunch of them into an array When we're ready, we can loop through the lot, calling output() without worrying about the mechanics From a single array of Table-derived objects, we can write emails, HTML, XML, or plain text, simply by repeatedly calling output()!
Summary
It is not possible to introduce you to all the aspects of object-oriented programming
in one short hour, but I hope I have introduced you to some of the possibilities
The extent to which you use objects and classes in your projects is a matter of choice It is likely that heavily object-oriented projects will be somewhat more
Trang 17resource-intensive at runtime than more traditional code However, effective deployment of object-oriented techniques can significantly improve the flexibility and organization of your code
Throughout this hour, you learned how to create classes and instantiate objects from them You learned how to create and access properties and methods Finally, you learned how to build new classes that inherit and override the features of other classes
Q&A
Q This hour introduced some unfamiliar concepts Do I really need to understand object-oriented programming to become a good PHP programmer?
A The short answer is no Most PHP scripts use little or no object-oriented code at all
The object-oriented approach won't help you do things that you couldn't otherwise achieve The benefits of object-oriented programming lie in the organization of your scripts, their reusability, and their extensibility
Even if you decide not to produce object-oriented code, however, you may need to decipher third-party programs that contain classes This hour should help you understand such code
Q I'm confused by the special variable $this
A Within a class, you sometimes need to call the class's methods or access its
properties By combining the $this variable and the -> operator, you can do both The $this variable is the handle a class is automatically given to refer to itself and to its components
Workshop
The Workshop provides quiz questions to help you solidify your understanding of the material covered Try to understand the quiz answers before continuing to the next hour's lesson Quiz answers are provided in Appendix A
Trang 18How can you declare a property within a class?
How would you choose a name for a constructor method?
How would you create a constructor method in a class?
How would you create a regular method within a class?
How can you access and set properties or methods from within a class?
How would you access an object's properties and methods from outside the object's class?
What should you add to a class definition if you want to make it inherit functionality from another class?
Repeat activity 2, for a class called minusCalc() Give minusCalc() a calculate method that subtracts the first property from the second, outputting the result
to the browser
Trang 19Hour 9: Working with Forms
Overview
Until now, all examples in this book have been missing a crucial dimension You can set variables and arrays, create and call functions, and work with objects All this is meaningless if users can't reach into a language's environment to offer it information In this hour, you will look at strategies for acquiring and working with user input
On the World Wide Web, HTML forms are the principal means by which substantial amounts of information can pass from the user to the server PHP is designed to acquire and work with information submitted via HTML forms
In this hour, you will learn
How to get and use environment variables
How to access information from form fields
How to work with form elements that allow multiple selections
How to create a single document that contains both an HTML form and the PHP code that handles its submission
How to save state with hidden fields
How to redirect the user to a new page
How to build HTML forms that upload files and how to write the PHP code to handle them
Global and Environment Variables
Before you actually build a form and use it to acquire data, you need to make a small detour and look again at global variables You first met these in Hour 6, "Functions."
A global variable is any variable declared at the "top level" of a script— that is, declared outside a function All functions are made available in a built-in associative array called $GLOBALS This is useful in Listing 9.1 because we can take a peek at all our script's global variables with a single loop
Listing 9.1: Looping Through the $GLOBALS Array
1: <html>
2: <head>
3: <title>Listing 9.1 Looping through the $GLOBALS array</title>
4: </head>
Trang 20Table 9.1: Environment Variables
$HTTP_USER_AGENT The name and
version of the client
Mozilla/4.6 (X11;I;Linux2.2.6-15apmac ppc)
$REMOTE_ADDR The IP address
of the client
158.152.55.35
$REQUEST_METHOD Whether the
request was GET or POST
POST
requests, the encoded data send appended
to the URL
name=matt&address=unknown
$REQUEST_URI The full address /matt/php-
Trang 21of the request including query string
book/forms/eg9.14.html?
name=matt
$HTTP_REFERER The address of
the page from
request was made
http://www.test.com/a_page.html
In addition to environment variables, PHP makes some other global variables available to you The variable $GLOBALS["PHP_SELF"], for example, gives you the path to the script currently running On my system this was as follows:
/matt/php-book/forms/eg9.1.php
This variable can also be directly accessed as the global variable $PHP_SELF This will be useful in many of the examples in this hour We will often include the HTML forms we use in the same page as the PHP code that analyzes the content they submit We can use $PHP_SELF as the string assigned to the HTML FORM element's ACTION argument, saving us the trouble of hard-coding the name of the page PHP's $GLOBALS array will become useful in other ways as well
A Script to Acquire User Input
For now, we'll keep our HTML separate from our PHP code Listing 9.2 builds a simple HTML form
Listing 9.2: A Simple HTML Form
6: <form action="eg9.3.php" method="GET">
7: <input type="text" name="user">
Trang 22We define a form that contains a text field with the name "user", a text area with the name "address", and a submit button It is beyond the remit of this book to cover HTML in detail If you find the HTML in these examples hard going, take a look at
Sams Teach Yourself HTML in 24 Hours or one of the numerous online HTML
tutorials The FORM element's ACTION argument points to a file called eg9.3.php, which processes the form information Because we haven't added anything more than a filename to the ACTION argument, the file eg9.3.php should be in the same directory on the server as the document that contains our HTML
Listing 9.3 creates the code that receives our users' input
Listing 9.3: Reading Input from the Form in Listing 9.2
7: print "Welcome <b>$user</b><P>\n\n";
8: print "Your address is:<P>\n\n<b>$address</b>";
9: ?>
10: </body>
11: </html>
This is the first script in this book that is not designed to be called by hitting a link
or typing directly into the browser's location field We include the code from Listing 9.3 in a file called eg9.3.php This file is called when a user submits the form defined
in Listing 9.2
In the code, we have accessed two variables, $user and $address It should come as
no surprise that these variables contain the values that the user added to the text field named "user" and the text area named "address" Forms in PHP4 really are as simple as that Any information submitted by a user will be available to you in global variables that will have the same names as those of the form elements on an HTML page
Accessing Input from Multiple SELECT Elements
The examples so far enable us to gather information from HTML elements that submit a single value per element name This leaves us with a problem when working with SELECT elements These elements make it possible for the user to