More Books
PHP 5 Unleashed
PHP 5 Unleashed
Table of Contents
Copyright
Lead Author
Contributing Authors
Acknowledgments
We Want to Hear from You!
Reader Services
Introduction
Organization of the Book
Part I. Working with PHP for General Web Development
Chapter 1. Basic PHP Development
How PHP Scripts Work
Basic PHP Syntax
Basic PHP Data Types
Variable Manipulation
Control Structures
User-Defined Functions
Dynamic Variables and Functions
Multiple File PHP Scripts
References
Strings in PHP
Comparing Strings
Advanced String Comparison
Search and Replacement
Formatting Strings
Strings and Locales
Formatting Date and Time Values
Summary
Chapter 2. Arrays
Basic Arrays
Implementing Arrays
More Array Materials
Chapter 3. Regular Expressions
The Basics of Regular Expressions
Limitations of the Basic Syntax
POSIX Regular Expressions
Perl-Compatible Regular Expressions (PCRE)
PCRE Modifiers
A Few Final Words
Chapter 4. Working with Forms in PHP
HTML Forms 101
Working with Form Submissions in PHP
Summary
Chapter 5. Advanced Form Techniques
Data Manipulation and Conversion
Form Data Integrity
Form Processing
Summary
Chapter 6. Persistent Data Using Sessions and Cookies
HTTP Cookies
PHP Sessions
Advanced Sessions
Summary
Chapter 7. Using Templates
The What and Why of Templates
The Smarty Template Engine
Summary
Part II. Advanced Web Development
Chapter 8. PEAR
What Is PEAR?
Getting and Installing PEAR
Using the PEAR Package Manager
Using the PEAR Website
Using PEAR Packages in Applications
Summary
Reference
Chapter 9. XSLT and Other XML Concerns
Relating XML to HTML
Using XSLT to Describe HTML Output Using XML Input
PHP4 and XSLT Using the DOM XML Module
PHP4 and XSLT Using the XSLT Module
PHP5 and XSLT
Accessing XML Data Using SimpleXML
Generating XML Documents Using PHP
Summary
References
Chapter 10. Debugging and Optimizations
Debugging Your PHP Scripts
Optimizing Your PHP Scripts
Summary
Chapter 11. User Authentication
Authenticating Users in PHP
Securing PHP Code
Summary
Chapter 12. Data Encryption
Shared Secret Versus Public Key
Shared Secret Algorithms
Public Key Cryptography
Using Public Keys in PHP
Summary
Chapter 13. Object-Oriented Programming in PHP
Why Objects?
Creating Basic Classes
Advanced Classes
Special Methods
Class Autoloading
Object Serialization
Exceptions
Iterators
Summary
Chapter 14. Error Handling
The PHP Error-Handling Model
What to Do About Errors
The Default Error Handler
Error Suppression
Custom Error Handlers
Causing Errors
Putting It All Together
Summary
Chapter 15. Working with HTML/XHTML Using Tidy
Introduction
Basic Tidy Usage
Tidy Configuration Options
Using the Tidy Parser
Applications of Tidy
Summary
Chapter 16. Writing Email in PHP
The MIME Protocol
Implementing MIME Email in PHP
Summary
Part III. Building Applications in PHP
Chapter 17. Using PHP for Console Scripting
Core CLI Differences
Working with PHP CLI
CLI Tools and Extensions
Summary
Chapter 18. SOAP and PHP
What Are Web Services?
Installation
Creating Web Services
Consuming Web Services
Looking for Web Services
Summary
Chapter 19. Building WAP-Enabled Websites
What Is WAP?
System Requirements
Introduction to WML
Serving WAP Content
Sample Applications
Summary
Part IV. I/O, System Calls, and PHP
Chapter 20. Working with the File System
Working with Files in PHP
File Permissions
File Access Support Functions
Summary
Chapter 21. Network I/O
DNS/Reverse DNS Lookups
Socket Programming
Network Helper Functions
Summary
Chapter 22. Accessing the Underlying OS from PHP
Introduction
Unix-Specific OS Functionality
Platform-Independent System Functions
A Brief Note About Security
Summary
Part V. Working with Data in PHP
Chapter 23. Introduction to Databases
Using the MySQL Client
Basic MySQL Usage
Summary
Chapter 24. Using MySQL with PHP
Performing Queries from PHP
A MySQLi Session Handler
What Is a Custom Session Handler?
Summary
Chapter 25. Using SQLite with PHP
What Makes SQLite Unique?
Basic SQLite Functionality
Working with PHP UDFs in SQLite
Odds and Ends
Summary
Chapter 26. PHP's dba Functions
Preparations and Settings
Creating a File-Based Database
Writing Data
Reading Data
Sample Application
Conclusion
Part VI. Graphical Output with PHP
Chapter 27. Working with Images
Basic Image Creation Using GD
Using the PHP/GD Drawing Functions
Working with Colors and Brushes
Using Fonts and Printing Strings
General Image Manipulation
Other Graphics Functions
Summary
Chapter 28. Printable Document Generation
A Note Regarding the Examples in This Chapter
Generating Dynamic RTF Documents
Generating Dynamic PDF Documents
Related Resources
Part VII. Appendixes
Appendix A. Installing PHP5 and MySQL
Installing PHP5
Installing MySQL and PHP Modules
Installing PEAR
Appendix B. HTTP Reference
What Is HTTP?
PHP Programming Libraries for HTTP Work
Understanding an HTTP Transaction
HTTP Client Methods
What Comes Back: Server Response Codes
HTTP Headers
Encoding
Identifying Clients and Servers
The "Referer"
Fetching Content from an HTTP Source
Media Types
Cookies: Preserving State and a Tasty Treat
Security and Authorization
Client-Side Caching of HTTP Content
Appendix C. Migrating Applications from PHP4 to PHP5
Configuration
Object-Oriented Programming (OOP)
New Behavior of Functions
Further Reading
Appendix D. Good Programming Techniques and Performance Issues
Common Style Mistakes
Common Security Concerns
Style and SecurityLogging
Summary
Appendix E. Resources and Mailing Lists
Relevant Websites
Mailing Lists and Newsgroups
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z

Creating Basic Classes

Although we call this style of programming object-oriented programming, the great majority of all the programming is done developing classes. A class can be thought of as a blueprint of an object and defines all the actions that object is capable of. Class definitions thus contain variables, functions (called methods), and even constants that are specific to that class or its instances only. In PHP 4, a basic class was defined as shown in Listing 13.1:

Listing 13.1. A Basic PHP 4 Class
<?php
    class myPHP4Class {
        var $my_variable;
        function my_method($param) {
            echo "Hello, you called my_method($param)!\n";
            echo "The value of my variable is: ";
            echo "{$this->my_variable}\n";
        }
    }
?>

After a class is defined, an instance of that class can be created. A instantiated class is an object and represents a working copy of the previously-defined class. To create an instance of the myPHP4Class class, the new statement is used:

<?php
     include_once ("myPHP4Class_def.php");
     $myinstance = new myPHP4Class();
     $anotherinstance = new myPHP4Class();
?>

In this case, the $myinstance and $anotherinstance variables both represent objects of type myPHP4Class. Although they were created from the same class definition, they are completely independent of each other.

After an instance of a class has been created, the properties and methods defined by that class may be accessed for that instance by using the -> operator. For instance, continuing from the previous example, Listing 13.2 sets the $my_variable property of each instance:

Listing 13.2. Basic Object Accessing
<?php
     $myinstance = new myPHP4Class();
     $anotherinstance = new myPHP4class();
     $myinstance->my_variable = 10;
     $anotherinstance->my_variable = 20;
     $myinstance->my_method("MyParam");
?>

When executed, the $my_variable property of the $myinstance object will be set to 10, and the $anotherinstance $my_variable property will be set to 20. Because this script calls the my_method() method of the class, the following output will be generated as well:

Hello, you called my_method(MyParam)!
The value of my variable is 10

NOTE

$this is a special variable within a class that represents the instance of the object itself. It is used to access both methods and properties internally within the object.


Private, Protected, and Public

In PHP 5, defining and using classes have not changed a great deal. In fact, it is no mistake that the code in Listing 13.1 will still work as expected in PHP 5. This is, however, a deprecated method of defining a class. The new method of defining the preceding class is shown in Listing 13.3:

Listing 13.3. A Basic PHP 5 Class
<?php
     class myPHP5Class {
          public $my_variable;
          public function my_method($param) {
               echo "Hello, you called my_method($param)!\n";
               echo "The value of my variable is: ";
               echo "{$this->my_variable}\n";
          }
     }
?>

This difference brings us to an important new feature in the OO model of PHP 5access controls.

In PHP 4 there was no concept of access control within objects. As an outside developer using the myPHP4Class class, there is nothing stopping me from changing or reading the value of the $my_variable variable. In PHP 5, however, the object model now provides three access levels for class members, which restrict what data can be accessed from where in your scripts. These three access methods are public, private, and protected and can be applied both to methods and properties of the class as shown in Listing 13.3.

NOTE

Not only does PHP provide private, public, and protected when defining class members, but it is also deprecated not to specify an access level in PHP 5.


Class members that are declared public can be accessed from anywhere within a script. They can be called or modified internally by the object or from outside the object. This is not true for class members declared using private, which will allow access to the class member only from within an instance of that class through the $this variable. In Listing 13.4, consider the changes to the example in Listing 13.3:

Listing 13.4. Using private and public in Classes
<?php
     class myPHP5Class {
          private $my_variable;
          public function my_method($param) {
               echo "Hello, you called my_method($param)!\n";
               echo "The value of my variable is: ";
               echo "{$this->my_variable}\n";
          }
     }
?>

When an instance of myPHP5Class is created, attempting to access the $my_variable property from outside the object will cause an error in PHP:

<?php
     $myobject = new myPHP5Class();
     /* This is allowed, as my_method is declared public */
     $myobject->my_method("MyParam");
     /* This will cause an error, $my_variable is private */
     $myobject->my_variable = 10;
?>

When the preceding code is executed, the following error will occur:

Fatal Error: Cannot access private property myPHP5Class::my_variable in ....

The third and final access level PHP provides is the protected level. This level is similar to private, as it prevents access to the class member externally. However, unlike private, which restricts access to only the specific class where it is defined, protected allows access from both itself and any child classes. For more information regarding child classes and inheritance, see "Class Inheritance" later in this chapter.

Type Hinting

Another improvement in PHP 5 to the object model is the concept of type hinting. PHP is, by design, a typeless language. That is, variables are not restricted to what data type they can contain. In fact, the same variable can at one point be treated as an integer and the next as a string. However, because methods within objects often accept parameters that are instances of other objects, PHP 5 allows you to restrict the data types of method parameters. Consider the example in Listing 13.5:

Listing 13.5. Type Hinting in PHP5
<?php
     class Integer {
          private $number;
          public function getInt() {
               return (int)$this->number;
          }
          public function setInt($num) {
               $this->number = (int)$num;
          }
     }
     class Float {
          private $number;
          public function getFloat() {
               return (float)$this->number;
          }
          public function setFloat($num) {
               $this->number = (float)$num;
          }
     }
?>

Listing 13.5 defines two classes, Integer and Float, which implement a simple wrapper for these data types within PHP. What if a class needed to be implemented that added only two floats together? With our current knowledge, the following would be our solution:

<?php
     class Math {
          public function add($op1, $op2) {
               return $op1->getFloat() + $op2->getFloat();
          }
     }
?>

However, because of the nature of PHP, there are no assurances that the $op1 and $op2 parameters will be instances of the Float class. Even if we are sure that they are objects, there is no convenient way to tell if they are of the correct type. One possible solution is to use the new instanceof operator in PHP5, which returns a Boolean value indicating whether a variable is an instance of a particular class (see Listing 13.6):

Listing 13.6. Using the instanceof Operator
<?php
     class Math {
          public function add($op1, $op2) {
               if(($op1 instanceof Float) &&
                  ($op2 instanceof Float)) {
                    return $op1->getFloat() + $op2->getFloat();
               } else {
                    echo "Must pass two Floats!\n";
               }
          }
     }
?>

In Listing 13.6, our Math class now has a method of ensuring that the parameters that were passed are objects of the correct type. However, such a technique can easily make your code bug prone and confusing to read. A much better approach, which accomplishes the same goal, is to specify the exact type you need in the function prototype, as shown in Listing 13.7:

Listing 13.7. Using Object Type Hinting in PHP5
<?php
     class Math {
          public function add(Float $op1, Float $op2) {
               return $op1->getFloat() + $op2->getFloat();
          }
     }
?>

In this fashion, we are able to cleanly identify the specific type required by the add() method and can safely assume the getFloat() method will exist. As you will see later, type hinting can become very useful when used in conjunction with something called Interfaces (see "Interfaces" later in the chapter).

Cloning

In PHP4, objects were not represented by reference. That is, when an object was passed to a function or method call, a copy was made of that object. Not only was this a real hassle, but it could also result in some very difficult to track down bugs. Because a copy of the object was made, any modifications to that object instance made within a method or function affected only the copy within the function. This counterintuitive behavior has been corrected in PHP5; now all objects are represented by reference. Although an important change, this means that making direct copies of an instance of an object is no longer possible:

<?php
     $class_one = new MyClass();
     $class_one_copy = $class_one;
?>

In this example, you would expect that $class_one_copy would indeed be an independent instance of the MyClass class with all the traits of the $class_one instance. Although this would have been true in PHP 4, in PHP 5 both $class_one and $class_one_copy represent the same objectany modifications made to either instance will cause the same change in the other. In PHP 5, rather than directly assigning an instance of an object to a new variable, the clone statement must be used. This statement returns a new instance of the current object, copying the values of any member properties into it and thus creating an independent clone.

Therefore, in PHP 5 the code shown in Listing 13.8 would be used to create an independent copy of an instantiated object:

Listing 13.8. Using the clone Statement
<?php
     $class_one = new MyClass();
     $class_one_copy = clone $class_one;
?>

When you use the clone statement, by default an exact copy of the object being cloned is returned. However, a class can also implement the special __clone() method, which enables you to control what elements will be copied from one instance to another. In this special method, the $this variable references the new copy of the object, complete with all the values from the original. See Listing 13.9 below for using the __clone() method to control the values of the cloned object:

Listing 13.9. Using the __clone() Method
<?php
     class myObject {
          public $var_one = 10;
          public $var_two = 20;
          function __clone() {
               /* Set $var_two in the clone to 0 */
                    $this->var_two = 0;
          }
     }
     $inst_one = new myObject();
     $inst_two = clone $inst_one;
     var_dump($inst_one);
     var_dump($inst_two);
?>

In this example, the output will be as follows:

object(myObject)#1 (2) {
  ["var_one"]=>
  int(10)
  ["var_two"]=>
  int(20)
}
object(myObject)#2 (2) {
  ["var_one"]=>
  int(10)
  ["var_two"]=>
  int(0)
}

The __clone() method can be useful in any number of situations, the most likely is when the object being cloned contains information that is truly specific to that instance alone (such as a unique object identifier). In these cases, __clone() can be used to copy only that information that makes sense to copy.

Constructors and Destructors

Constructors and destructors are functions that are called when a new instance of an object is created (constructors) and/or destroyed (destructors). Their primary purpose is to allow for a means to initialize and clean up after an object during its use. In PHP 4, only constructors were available and were created by defining a function whose name was the same as the class itself:

<?php
     class SimpleClass {
          function SimpleClass($param) {
               echo "Created a new instance of SimpleClass!";
          }
     }
     $myinstance = new SimpleClass;
?>

In PHP 5, this concept has been improved considerably. To begin, PHP 5 now uses a unified constructor function named __construct(). PHP 5 also uses a unified __destruct() method for its destructors. Thus, in PHP 5 a reimplementation of the preceding SimpleClass example would look something like the code shown in Listing 13.10:

Listing 13.10. Using Unified Constructors and Destructors
<?php
     class SimpleClass {
          function __construct($param) {
               echo "Created a new instance of SimpleClass!";
          }
          function __destruct() {
               echo "Destroyed this instance of SimpleClass";
          }
     }
     $myinstance = new SimpleClass("value");
     unset($myinstance);
?>

Although constructors are intuitively useful for initializing class properties, the combination of constructors and destructors is equally useful in other ways. One classic example is a class to access a database back end, where a constructor could make the connection to the database while the destructor closes it.

Class Constants

Class constants are a new feature to PHP 5 that provide, as the name implies, a facility to define constant values within a class definition. To define a constant within a class, the const keyword is used, followed by the name of the constant to define and its value, as shown in Listing 13.11:

Listing 13.11. Using Class Constants in PHP5
<?php
     class ConstExample {
          private $myvar;
          public $readme;
          const MY_CONSTANT = 10;

          public function showConstant() {
               echo "The value is: ".MY_CONSTANT;
          }
     }
     $inst = new ConstExample;
     $inst->showConstant();
     echo "The value: ".ConstExample::MY_CONSTANT;
?>

Listing 13.11 illustrates the use of class constants in both the class itself and from outside the class. In this example, a single constant MY_CONSTANT has been defined in the class with an integer value of 10. This constant can be accessed anywhere within the class itself directly, just as with any constant created using the define() function. However, to access the constant from outside the class, it must be referenced along with the class name that defines the constant in <CLASSNAME>::<CONSTANT> format. Class constants, like all other class members, are inherited from parent classes and can be overridden by child classes (for more information on inheritance, see "Class Inheritance" later in this chapter).

Static Methods

Static methods are methods that are part of a class, but that are designed to be called from outside the context of the instance of an object. They behave identically to normal methods in a class in every way minus one significant detailstatic methods cannot use the $this variable to reference the current instance of the object.

To create a static method, add the static keyword in front of any class method declaration:

static function myMethod() {
...

Because static methods are not associated with a particular instance of an object, they can be called from outside the context of an instantiated object. To call a static method in this fashion, the syntax is as follows:

<CLASSNAME>::<METHOD>

<CLASSNAME> represents the class where the static method resides and <METHOD> is the method to call. Note that static methods can also be called from the context of an instantiated object as well; however, they still do not have access to the $this instance variable.

Class Inheritance

In both PHP 4 and PHP 5, object-oriented programming is designed around a single-inheritance model. Inheritance is, by definition, the capability for one class definition to extend another class definition's functionality. When one class inherits from another, all of the parent's methods, properties, and constants are available from the child class as well. Furthermore, child classes can also reimplement some or all of the methods, properties, and constants of a parent class to provide additional or different functionality. Classes are inherited from one another using the extends keyword in the class definition. Consider the example in Listing 13.12:

Listing 13.12. Class Inheritance
<?php
     class ParentClass {
          public $parentvar;
          public function parentOne() {
               echo "Called parentOne()\n";
          }
          private function parentTwo() {
               echo "Called parentTwo()!\n";
          }
     }

     class ChildClass extends ParentClass {
          public function childOne() {
               echo "Called childOne()!\n";
          }

          /* No need to define the parentOne() method, it was
             already inherited from the ParentClass class */

     }

     $v = new ChildClass();
     $v->parentOne();
?>

In this example I have defined two classes: ParentClass and ChildClass (which extends ParentClass). Although each of these classes implements its own unique set of functions, because Childclass extends the ParentClass class it includes all the properties and methods that it has access to as well. This is where the access-level concepts of private, public, and protected come into play the most. When inheriting methods and properties from another class, only those class members declared public or protected will be available within the child class.

NOTE

When I first introduced public, private, and protected, I omitted describing protected in any great detail. As you can see, the reason is that to understand protected you must first understand inheritance. When a class member is declared as protected, it is only available within the context of the class itself or any child classes that inherit from it.


When considering inheritance, it is also important to understand how class members are bound. Consider Listing 13.13:

Listing 13.13. Class Member Overloading
<?php
     class ParentClass {
          public function callMe() {
               echo "Parent called!\n";
          }
     }
     class ChildClass extends ParentClass {
          public function callMe() {
               echo "Child called!\n";
          }
     }
     $child = new ChildClass;
     $child->callMe();
?>

When the preceding script is executed, what will happen? You have already learned that child classes will inherit class members from a parent, but what if the child also implements the same class member itself? In situations such as when calling the callMe() method in Listing 13.13, the method which is actually executed is the one found in the ChildClass version. This principle of preferring the "local" class member is a critical part of OO programming; in fact, it also applies to parent classes as well. Consider the example in Listing 13.14:

Listing 13.14. Class Member Binding in PHP
<?php
     class ParentClass {
          public function callMe() {
               $this->anotherCall();
          }
          public function anotherCall() {
               echo "Parent called!\n";
          }
     }
     class ChildClass extends ParentClass {

          public function anotherCall() {
               echo "Child called!\n";
          }
     }
     $child = new ChildClass;
     $child->callMe();
?>

In this example, when the callMe() method is called, what will happen? Because the callMe() method is not defined in the ChildClass class, the one from ParentClass will be used. Looking at the callMe() method in ParentClass, note that it calls a second method as well: anotherCall(). Although PHP is executing the callMe() method from the ParentClass class, when executed it will be the ChildClass anotherCall() function that is executed, even though it also exists in the ParentClass class. The reason is that in PHP (as is the case with most languages support OOP), $this will always reference the instance of the class that called the method of the class (in this case ChildClass), regardless of where the code resides.