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

PHP Sessions

One of the most useful applications of cookies is the capability to create sessions, which truly allow you to overcome the state-less nature of the HTTP protocol. When working with sessions in PHP, you are given the capability to store variables (including arrays and classes) between script executions and recall them later. For this system to function, the Web server must be able to identify one Web browser from another, and this is where cookies play their role. Unlike my previous example of using cookies to identify a user, sessions do not actually store any significant information on the client machine. As with the car valet analogy, sessions work on the concept that each individual client browser is given a "ticket" (called a session ID), which is then presented to the Web server during every request. This session ID is then matched up with the relevant data and that data is again made available from within your PHP scripts.

Although sessions do offer a fair amount of security (because no sensitive information is being stored on the client browser itself), sessions are by no means completely secure. Because all the data for a particular user is tied to a single identifying string, it is possible (although unlikely) for a malicious user to hijack a session by guessing or otherwise acquiring a valid session ID. This may or may not be a serious issue, depending on the need for security on your website. It is generally considered good practice to develop a website under the assumption that a session will be hijacked; thus all critical pieces of data (credit card numbers, for example) should always be inaccessible if the session ID is compromised.

Basic Session Use

In this section, I discuss the basics of registering, unregistering, and working with session variables in PHP. It is important to note that manipulation of session variables using functions being introduced here such as session_register(), session_unregister(), and session_is_registered() should be used only if you have the register_globals PHP directive activated. If this directive is not activated (recommended), then all session variables must be manipulated using the $_SESSION superglobal array.

Starting a Session

There are three primary ways to create a session within PHP. The first method is to directly order PHP to begin a session by using the session_start() function. This function takes no parameters and has no return value. When this function is called, any variables that are associated this session will be reconstructed. This can also be accomplished by using the session_readonly() function, the second approach, which is used in place of the session_start() function. When this alternative is used, the session variables will all be re-created; however, any changes made to those variables will not be saved when the script terminates.

NOTE

In PHP, sessions work only with variables within the global scope. This means that to register a variable from a function, that variable must be declared global using the global statement. Likewise, PHP also reconstructs only variables within the global scope.


As I said, there are three ways to start a session within a PHP script. The third is to register a variable using the session_register() function.

Registering Session Variables

When registering a session variable, there are two methods of doing so. The first is to use the session_register() function. The syntax for this function is as follows:

session_register($var_name [, $next_varname [, ...]])

$var_name (as well as any other additional parameters) are strings (or arrays of strings) representing the variable to store in the session. This function returns a Boolean true if all the variables provided were stored successfully, or it returns false on failure. Because the session_register() function does begin a session if it does not already exist, be aware that all calls to session_register() must be completed before any output is sent to the browser. Thus, although it is possible to begin a session using this function, it is better practice to manually begin a session using session_start() or similar facility first.

When you are working with session variables, there are some things that must be considered for things to work properly. To save you the time of finding them all out yourself, I will take a moment to explain these little details.

One of the most common mistakes for users when first working with PHP sessions is to automatically assume that the parameters passed to it are the actual variables to store in the session. However, session_register() accepts only strings representing the name of the variable to store in the session. This is most clearly illustrated by the following snippet (see Listing 6.7):

Listing 6.7. Using the session_register() Function
<?php
    $myvar = "This is my variable to store in the session";
    $myvar_name = "myvar";
    session_register($myvar_name);
?>

When this code is executed, what is stored in the session? As you recall, the $myvar variable will be registered, not $myvar_name. If you are still confused, let me explain further. I have created two variables: $myvar, which is the actual value I'd like to save in the session, and $myvar_name. When the session_register() function is executed, PHP will attempt to store into the session the variable whose name is stored into the $myvar_name variable (not the $myvar_name variable itself). Because this variable has a value of myvar, the $myvar variable will be stored into the session.

For those who would rather not (or cannot, if the register_globals directive is disabled) use the session_register() function for working with session variables, PHP also provides the superglobal $_SESSION array. During the course of any session, the $_SESSION variable can be accessed and manipulated in the same manner as if the session_register() had been used. For instance, if you wanted to store the contents of $myvar from my previous example in a session using the superglobal method, the following would work:

$_SESSION['myvar'] = $myvar;

When you use this method to work with session variables, the session_register() function should not be used. Also, unlike when you work with the session_register() function, a session will not automatically be created by storing a variable in the $_SESSION superglobal. Hence, it is important that you explicitly begin a session prior to working with the $_SESSION superglobal.

Unregistering Session Variables

There are times (for instance, when a user logs out) when it is necessary to remove session variables. This can be done by destroying the entire session or by removing only certain session variables. To remove certain variables, you could either use the unset statement to remove the entry from the $_SESSION superglobal or use the session_unregister() PHP function. The syntax of the session_unregister() function is as shown next:

session_unregister($name)

Like its counterpart, session_register(), session_unregister() takes a string $name representing the global variable name to remove from the stored session variables. This function returns a Boolean true if the variable was removed successfully or returns false if the variable didn't exist.

Destroying Sessions

If you would like to destroy all the session variables (as well as the entire session), the session_destroy() function is used. Accepting no parameters, this function will destroy any cookies and data associated with the active session.

Working with Session Variables

Another possible need when working with sessions is to determine whether a session variable has been registered. This can be accomplished by using the isset statement to check for the existence of the proper key in the $_SESSION superglobal or by using the session_is_registered() function:

session_is_registered($name)

$name is a string representing the name of the session variable to check for. This function returns a Boolean TRue if the variable is registered or returns false if it is not.

To really demonstrate how sessions work in PHP, first we will need a situation where user-specific data must be saved across server requests. One ideal example with these sorts of requirements is an online shopping cart. For example, assume that all the functionality of the shopping cart script has been wrapped into a single PHP class called ShoppingCart. In this situation, for every individual shopper, an instance of the shopping cart is created only once and registered as a session variable by storing it in the $_SESSION superglobal. For each subsequent request, that instance (and all its data) is then re-created by PHP. Listing 6.8 illustrates the implementation of such a shopping cart system:

Listing 6.8. A Shopping Cart Class Example in PHP
ShoppingCart.class.php

<?php

class ShoppingCart {

        private $cart;

        function __construct() {
            $this->cart = array();
        }

        public function addItem($id, $name, $cost) {

            foreach($this->cart as $key=>$items) {
                if($items['id'] == $id) {
                    $this->cart[$key]['quantity']++;
                    return;
                }
            }

            $this->cart[] = array('id' => $id,
                                  'name' => $name,
                                  'cost' => $cost,
                                  'quantity' => 1);
        }

        public function delItem($id) {
            foreach($this->cart as $key => $items) {
                if($items['id'] == $id)
                    if($items['quantity'] > 1) {
                        $this->cart[$key]['quantity']--;
                    } else {
                        unset($this->cart[$key]);
                    }
                    return true;
                }
            }
            return false;
        }

        public function getCart() {
            return $this->cart;
        }

        public function clearCart() {
            $this->cart = array();
        }
}
?>

Listing6_8.php
<?php
    require_once("ShoppingCart.class.php");
        session_start();
        if(!isset($_SESSION['cart']) || !is_object($_SESSION['cart'])) {
               $_SESSION['cart'] = new ShoppingCart();

                /* Add a book to the shopping cart (item #43 for $49.95) */
               $_SESSION['cart']->addItem(43, "Book: PHP Unleashed", 49.95);
        }

?>

Although PHP has no problem using instances of objects as session variables, unlike any other data type in PHP, for an object to be re-created from a session, the initial class must be defined in the PHP script. This means that the ShoppingCart class definition itself must be included in the script for the $_SESSION['cart'] variable to be properly re-created.

Session Propagation

Now that you have an understanding of how sessions work from a function perspective, let's examine what types of practices are necessary for your sessions to function properly. As you know, individual sessions are identified by PHP through the use of a session ID, which is usually stored on the client machine in the form of an HTTP cookie. When cookie support is not available, this session ID must be propagated through the URL itself. To facilitate this, PHP provides the SID constant, which contains the current session ID name and value in the following format:

<session name>=<session id>

Because there are times when the format provided by the SID constant may not be desirable (as you'll see when propagating the session through an HTML form), PHP also provides two functions, session_name() and session_id(), which return the session name and its associated session ID, respectively. Regardless of the method used, the session ID must be used anytime a URL is provided that links to a nonexternal resource. For instance, for cases where a hyperlink is used, usually the SID constant works beautifully:

<A href="checkout.php?<?php echo SID; ?>">Proceed to checkout</A>

On the other hand, when working with HTML forms in general, the session ID is propagated through the use of a hidden form element. For situations such as this, the session_name() and session_id() functions must be used to fill in the appropriate values:

<FORM ACTION="order.php" METHOD=GET>
<INPUT TYPE="hidden" NAME="<?php echo session_name(); ?>"
                       VALUE="<?php echo session_id(); ?>">
<!-- The remainder of the form HTML code //-->
</FORM>

It is very important to realize when propagating the session ID that it must be done only when the URL resides on your local Web server. To avoid negative security implications, at no time should the session ID be passed to an external URL.

As you may be thinking already, attempting to ensure that every single possible URL in your HTML documents is correctly propagating the session ID could quickly become an incredibly painful task. In most cases, URLs can be rewritten automatically by enabling transparent session ID propagation by enabling the session.use_trans_sid configuration directive. When transparent session propagation is enabled, PHP will attempt to automatically append the session ID to the appropriate HTML tags.

NOTE

PHP determines what URLs are rewritten in the output being sent to the browser by the url_rewriter.tags configuration directive. This directive is a comma-separated list of values in the following format:

<HTML tag>=<Attribute>

<HTML tag> is the HTML tag that should be processed, and <Attribute> is the attribute of that HTML tag that contains the URL to rewrite. For your reference, the default value for the url_rewriter.tags directive is as follows:


url_rewriter.tags = "a=href,area=href,frame=src,input=src
,form=fakeentry"


When using transparent session ID propagation, PHP will rewrite relative URLs only for security reasons. Even though http://www.coggeshall.org/index.php and /index.php may be the same resource, PHP will append the session ID only to the latter of the two. This is to prevent the already mentioned security risk of passing a valid session ID to an external website. Hence, when using transparent session ID propagation, it is important to ensure that all your nonexternal URLs are written using the accepted relative URL format.