MySQL
®
/PHP
Database
Applications,
Second Edition
Brad Bulger, Jay Greenspan,
and David Wall
MySQL
®
/PHP Database Applications,
Second Edition
MySQL
®
/PHP
Database
Applications,
Second Edition
Brad Bulger, Jay Greenspan,
and David Wall
MySQL
®
/PHP Database Applications, Second Edition
Published by
Wiley Publishing, Inc.
10475 Crosspoint Boulevard
Indianapolis, IN 46256
www.wiley.com
Copyright © 2004 by Wiley Publishing, Inc., Indianapolis, Indiana
ISBN: 0-7645-4963-4
Manufactured in the United States of America
10 9 8 7 6 5 4 3 2 1
2O/RW/RQ/QT
Published by Wiley Publishing, Inc., Indianapolis, Indiana
Published simultaneously in Canada
No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by
any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under
Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of
the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance
Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher
for permission should be addressed to the Legal Department, Wiley Publishing, Inc., 10475 Crosspoint Blvd.,
Indianapolis, IN 46256, (317) 572-3447, fax (317) 572-4447, E-Mail:
is a trademark of Wiley Publishing, Inc.
LIMIT OF LIABILITY/DISCLAIMER OF WARRANTY: WHILE THE PUBLISHER AND AUTHOR HAVE
USED THEIR BEST EFFORTS IN PREPARING THIS BOOK, THEY MAKE NO REPRESENTATIONS OR
WARRANTIES WITH RESPECT TO THE ACCURACY OR COMPLETENESS OF THE CONTENTS OF THIS
BOOK AND SPECIFICALLY DISCLAIM ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
FITNESS FOR A PARTICULAR PURPOSE. NO WARRANTY MAY BE CREATED OR EXTENDED BY
SALES REPRESENTATIVES OR WRITTEN SALES MATERIALS. THE ADVICE AND STRATEGIES
CONTAINED HEREIN MAY NOT BE SUITABLE FOR YOUR SITUATION. YOU SHOULD CONSULT WITH
A PROFESSIONAL WHERE APPROPRIATE. NEITHER THE PUBLISHER NOR AUTHOR SHALL BE
LIABLE FOR ANY LOSS OF PROFIT OR ANY OTHER COMMERCIAL DAMAGES, INCLUDING BUT NOT
LIMITED TO SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR OTHER DAMAGES.
For general information on our other products and services or to obtain technical support, please contact our
Customer Care Department within the U.S. at (800) 762-2974, outside the U.S. at (317) 572-3993 or fax (317)
572-4002.
Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not
be available in electronic books.
Library of Congress Cataloging-in-Publication Data: 2002114859
Trademarks: Wiley, the Wiley Publishing logo, and related trade dress are trademarks or registered trademarks
of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries, and may not be used
without written permission. MySQL is a registered trademark of MySQL AB Company. All other trademarks
are the property of their respective owners. Wiley Publishing, Inc., is not associated with any product or vendor
mentioned in this book.
About the Authors
Brad Bulger can remember when computers were as big as refrigerators and old-
timers would come into the machine room and call them “mini.” After working for
several companies that no longer exist, he is now a member of The Madfish Group
(), where he builds Web sites for money. He would
still like to know when the future is going to get here but has a sneaking suspicion
he already knows.
Jay Greenspan is a New York–based writer, editor, and technical consultant. He
has contributed to sites run by Apple Computer and Wired Digital, and is author of
MySQL Weekend Crash Course. He runs Trans-City Productions, Inc. (http://www.
trans-city.com
), a firm that provides editorial services to high-tech companies.
David Wall is a freelance technical consultant, lecturer, and writer. He specializes
in Linux/Apache/MySQL/PHP (LAMP) servers and in Voice over IP technologies
from IBM and Cisco Systems. His consultancy, David Wall Enterprises (http://
www.davidwall.com
), has offices in Washington, D.C., and Sydney.
Credits
ACQUISITIONS EDITORS
Debra Williams Cauley
Jim Minatel
PROJECT EDITORS
Kevin Kent
Neil Romanosky
TECHNICAL EDITORS
Zak Greant
Bill Patterson
Liz Warner
COPY EDITOR
S. B. Kleinman
EDITORIAL MANAGER
Mary Beth Wakefield
VICE PRESIDENT & EXECUTIVE
GROUP PUBLISHER
Richard Swadley
VICE PRESIDENT AND
EXECUTIVE PUBLISHER
Bob Ipsen
VICE PRESIDENT AND PUBLISHER
Joseph B. Wikert
EXECUTIVE EDITORIAL DIRECTOR
Mary Bednarek
PROJECT COORDINATOR
Maridee Ennis
GRAPHICS AND PRODUCTION
SPECIALISTS
Beth Brooks
Jennifer Click
LeAndra Hosier
Michael Kruzil
PERMISSIONS EDITOR
Carmen Krikorian
MEDIA DEVELOPMENT SPECIALIST
Angela Denny
PROOFREADING AND INDEXING
TECHBOOKS Production Services
To Lizma, who’s still here; Jon Postel, who isn’t;
and a free Internet, which might not be much longer
For Catou
Preface
Welcome. If you are thumbing through these pages, you’re probably considering
writing Web-based applications with PHP and MySQL. If you decide to go with
these tools, you’ll be in excellent company. Thousands of developers — from total
newbies to programmers with years of experience — are turning to PHP and MySQL
for their Web-based projects, and for good reason.
Both PHP and MySQL are easy to use, fast, free, and powerful. If you want to get
a dynamic Web site up quickly, there are no better choices. The PHP scripting lan-
guage was built for the Web. All the tasks common to Web development can be per-
formed in PHP with an absolute minimum of effort. Similarly, MySQL excels at tasks
common to dynamic Web sites. Whether you’re creating a content-management sys-
tem or an e-commerce application, MySQL is a great choice for your data storage.
Is This Book for You?
Quite a few books deal with PHP, and a few cover MySQL. We’ve read some of these
and found a few to be quite helpful. If you’re looking for a book that deals with the
gory details of either of these packages, you should probably look elsewhere.
The focus of this book is applications development. We are concerned with what
it takes to get data-driven Web sites up and running in an organized and efficient
way. The book does not go into arcane detail of every aspect of either of these tools.
For example, in this book you will not find a discussion of PHP’s LDAP functions
or MySQL’s C application program interface (API). Instead, we focus on the pieces
of both packages that affect one another. We hope that by the time you’re done
with this book you’ll know what it takes to get an application up and running using
PHP and MySQL.
How This Book Is Organized
We have organized the book into five parts.
Part I: Working with MySQL
Before you code any PHP scripts you need to know how to design a database, cre-
ate tables in your database, and get the information you want from the database.
Part I of this book shows you just about everything you need to know to work with
MySQL.
ix
Part II: Working with PHP
As an applications developer, you will spend the bulk of your time writing scripts
that access the database and present HTML to a user’s browser. Part II starts by
showing you the basics of the PHP scripting language, covering how PHP works
with variables, conditions, and control structures. Part II also covers many of PHP’s
functions and discusses techniques for writing clean, manageable code.
Part III: Simple Applications
In this part we present two of the nine applications in this book: a guestbook and a
survey. Here you see the lessons from Parts I and II put into practice as we build
working applications.
Part IV: Not So Simple Applications
Here the applications become more complex, as we present applications commonly
used on the Web. You see how you can design a content management system, a
discussion board, a shopping cart, and other useful applications. Along the way
we show you some tips and techniques that should be helpful as you write your
applications.
Part V: Appendixes
The appendixes cover several topics of interest to the MySQL/PHP developer. In
them you can find installation and configuration instructions, quick reference
guides to PHP and MySQL functions, a regular expressions overview, and guides to
MySQL administration. In addition, you can find a few helpful resources, some
snippets of code, and instructions on using the CD-ROM.
x Preface
Acknowledgments
I owe so many people so many bags of chocolate peanuts for helping me that I
should start a chocolate-peanut farm. Making this book happen, trying to cover
products under very active development, has been like trying to paint an oil por-
trait of a manic chameleon in a camouflage factory. I must single out Debra
Williams Cauley, Acquisitions Editor, and Kevin Kent, Development Editor, for their
help and their patience — they have been the essence of diplomacy; Jay Greenspan,
for getting me into this; and Liz Warner, for all disclosed and undisclosed forms of
assistance, but especially for helping me stay sane(ish). Thanks so much to MySQL
AB for the generous use of the MySQL Function Reference in Appendix J, and to
Zak Greant, Erik Granstrom, Bill Patterson, and David Sides, CEO of Dolphin, for all
their assistance. To everyone who helped, thank you — you have our gratitude. —
Brad Bulger
Thanks to my friends, family, and colleagues for their support and freely shared
expertise during the creation of this book. — David Wall
xi
Contents at a Glance
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Part I Working with MySQL
Chapter 1 Database Design with MySQL . . . . . . . . . . . . . . . . . 3
Chapter 2 The Structured Query Language for Creating and
Altering Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Chapter 3 The Structured Query Language for Inserting,
Editing, and Selecting Data . . . . . . . . . . . . . . . . . . 53
Part II Working with PHP
Chapter 4 Getting Started with PHP — Variables . . . . . . . . . . . 91
Chapter 5 Control Structures . . . . . . . . . . . . . . . . . . . . . . . . 117
Chapter 6 PHP’s Built-in Functions . . . . . . . . . . . . . . . . . . . 133
Chapter 7 Writing Organized and Readable Code . . . . . . . . . 191
Part III Simple Applications
Chapter 8 Guestbook 2003, the (Semi-)Bulletproof
Guestbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Chapter 9 Survey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Part IV Not So Simple Applications
Chapter 10 Threaded Discussion . . . . . . . . . . . . . . . . . . . . . . 311
Chapter 11 Content-Management System . . . . . . . . . . . . . . . 349
Chapter 12 Catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
Chapter 13 Problem-Tracking System . . . . . . . . . . . . . . . . . . 441
Chapter 14 Shopping Cart . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
Chapter 15 XML Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Chapter 16 SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Chapter 17 Project Management . . . . . . . . . . . . . . . . . . . . . . 537
xii
Part V Appendixes
Appendix A What’s on the CD-ROM . . . . . . . . . . . . . . . . . . . . 557
Appendix B HTML Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
Appendix C Brief Guide to MySQL/PHP Installation and
Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 571
Appendix D MySQL Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Appendix E MySQL User Administration . . . . . . . . . . . . . . . . 597
Appendix F PHP Function Reference . . . . . . . . . . . . . . . . . . . 607
Appendix G Regular Expressions Overview . . . . . . . . . . . . . . . 659
Appendix H Helpful User-Defined Functions . . . . . . . . . . . . . . 669
Appendix I PHP and MySQL Resources . . . . . . . . . . . . . . . . . 691
Appendix J MySQL Function Reference . . . . . . . . . . . . . . . . . 697
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735
End-User License Agreement . . . . . . . . . . . . . . . . 765
xiii
Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Part I Working with MySQL
Chapter 1 Database Design with MySQL . . . . . . . . . . . . . . . . . . . . . 3
Why Use a Relational Database? . . . . . . . . . . . . . . . . . . . . . . 3
Blasted Anomalies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
The update anomaly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
The delete anomaly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
The insert anomaly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Normalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
First normal form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Second normal form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Third normal form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Types of Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
The one-to-many relationship . . . . . . . . . . . . . . . . . . . . . . . . 15
The one-to-one relationship . . . . . . . . . . . . . . . . . . . . . . . . . . 16
The many-to-many relationship . . . . . . . . . . . . . . . . . . . . . . . 17
Advanced Database Concepts . . . . . . . . . . . . . . . . . . . . . . . 19
Referential integrity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Chapter 2 The Structured Query Language for Creating
and Altering Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Essential Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Null values
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Indexes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
The create database Statement . . . . . . . . . . . . . . . . . . . . . . . 26
The use database Statement . . . . . . . . . . . . . . . . . . . . . . . . . 27
The create table Statement . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Column Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
String column types
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Numeric column types
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Date and time types
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Creating Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
xv
Table Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
MyISAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
InnoDB Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
BerkeleyDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
The alter table Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Changing a table name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Adding columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Dropping columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Adding indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Dropping indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Changing column definitions . . . . . . . . . . . . . . . . . . . . . . . . . 43
Using the show Command . . . . . . . . . . . . . . . . . . . . . . . . . . 44
show databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
show tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
show columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
show index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
show table status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
show create table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
GUI Tools for Manipulating MySQL Tables and Data . . . . . . 48
Using phpMyAdmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
MySQL Control Center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Using MacSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Chapter 3 The Structured Query Language for Inserting,
Editing, and Selecting Data . . . . . . . . . . . . . . . . . . . . . . 53
The insert Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
The update Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
The delete Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
The replace Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
The Basic select Statement . . . . . . . . . . . . . . . . . . . . . . . . . . 64
The where clause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
order by . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
limit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
group by and aggregate functions . . . . . . . . . . . . . . . . . . . . . 74
Joining Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
The two-table join (equi-join) . . . . . . . . . . . . . . . . . . . . . . . . . 80
The multi-table join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
The outer join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
The self join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Correlated subqueries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
xvi Contents
Part II Working with PHP
Chapter 4 Getting Started with PHP — Variables . . . . . . . . . . . . . 91
Assigning Simple Variables Within a Script . . . . . . . . . . . . . 91
Delimiting strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Assigning arrays within a script . . . . . . . . . . . . . . . . . . . . . . . 96
Assigning two-dimensional arrays in a script . . . . . . . . . . . . . . 99
Accessing Variables Passed from the Browser . . . . . . . . . . 100
HTML forms variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Passing arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Using Built-In Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
PHP variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Apache variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Other Web server variables . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Testing Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
isset() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
empty() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
is_null() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
is_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
is_double() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
is_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
is_array() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
is_bool() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
is_object() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
is_resource() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
is_scalar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
gettype() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Changing Variable Types . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Type casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Using settype() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
intval(), doubleval(), and stringval() . . . . . . . . . . . . . . . . . . . . 115
Variable Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Chapter 5 Control Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Determining true or false in PHP . . . . . . . . . . . . . . . . . . . . . . 118
Comparison operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Logical operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Complex if statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
if else statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
if elseif statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
switch case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Contents xvii
Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
do while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
foreach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
continue and break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Chapter 6 PHP’s Built-in Functions . . . . . . . . . . . . . . . . . . . . . . . 133
Function Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Return values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Function Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Important PHP Functions . . . . . . . . . . . . . . . . . . . . . . . . . 137
String handling functions . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Regular expression functions . . . . . . . . . . . . . . . . . . . . . . . . 142
Variable functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Type-conversion functions . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Array functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Object/class functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Print functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Date/time functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
File-system functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Script Control functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Random number generator functions . . . . . . . . . . . . . . . . . . 177
Session functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
MySQL functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
HTTP header functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Image functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Mail function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
URL functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Error functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Output buffering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Information functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Chapter 7 Writing Organized and Readable Code . . . . . . . . . . . 191
Indenting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Code blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Function calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
SQL statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Includes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
include() and require() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
include_once() and require_once() . . . . . . . . . . . . . . . . . . . . . 199
xviii Contents
User-Defined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Function basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Returning values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
Using a variable number of arguments . . . . . . . . . . . . . . . . . 205
Variable scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
Object-Oriented Programming . . . . . . . . . . . . . . . . . . . . . . 209
Classes, Continued . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Object cloning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Object-Oriented Code versus Procedural Code . . . . . . . . . . 220
Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Part III Simple Applications
Chapter 8 Guestbook 2003, the (Semi-)Bulletproof
Guestbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Determining the Scope and Goals of the Application . . . . 229
Necessary pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
What do we need to prevent? . . . . . . . . . . . . . . . . . . . . . . . . 231
Designing the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
From functions/basic.php . . . . . . . . . . . . . . . . . . . . . . . . . . 236
Interesting code flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Chapter 9 Survey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Determining the Scope and Goals of the Application . . . . . 261
Necessary pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Preventive measures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Designing the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
HTML functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
The survey application . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
Interesting Code Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
admin/questions.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
admin/get_winner.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
admin/winners.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
claim.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Contents xix
Part IV Not So Simple Applications
Chapter 10 Threaded Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
Determining the Scope and Goals of the Application . . . . . 312
What do you need? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
What do you need to prevent? . . . . . . . . . . . . . . . . . . . . . . . 314
The Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Reusable functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Functions from /book/discussion/functions . . . . . . . . . . . . . . 321
Error-handling and debugging functions . . . . . . . . . . . . . . . . 332
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Chapter 11 Content-Management System . . . . . . . . . . . . . . . . . . 349
Determining the Scope and Goals of the Application . . . . 350
Necessary pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
What do we need to prevent? . . . . . . . . . . . . . . . . . . . . . . . . 353
Designing the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
Functions from /dsn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
Functions from /book/functions/database . . . . . . . . . . . . . . . 365
Functions from /content/functions . . . . . . . . . . . . . . . . . . . . 374
Interesting Code Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
content/authenticate.php . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
content/admin/user.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
content/story.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
Chapter 12 Catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
Determining the Scope and Goals of the Application . . . . 398
Necessary pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
What do we need to prevent? . . . . . . . . . . . . . . . . . . . . . . . . 402
The Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
The object-oriented approach . . . . . . . . . . . . . . . . . . . . . . . . 408
Accessing the file system . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Uploading files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
Objects in theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Sample script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
xx Contents
Chapter 13 Problem-Tracking System . . . . . . . . . . . . . . . . . . . . . . 441
Determining the Scope and Goals of the Application . . . . . 441
What do you need? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
What do you need to prevent? . . . . . . . . . . . . . . . . . . . . . . . 444
Designing the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Reusable functions from /book/tracking/functions.php . . . . . . 453
Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
Chapter 14 Shopping Cart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
Determining the Scope and Goals of the Application . . . . 477
What do you need? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
What do you need to prevent? . . . . . . . . . . . . . . . . . . . . . . . 479
The Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
Configuration Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
Configuring for encryption and security . . . . . . . . . . . . . . . . 480
Configuring Apache for credit-card authorization . . . . . . . . . . 482
Configuring for session handling . . . . . . . . . . . . . . . . . . . . . 483
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
Session functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
Dealing with the credit-card processor . . . . . . . . . . . . . . . . . . 486
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Chapter 15 XML Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Scope and Goals of Application . . . . . . . . . . . . . . . . . . . . . 506
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
An introduction to parsers . . . . . . . . . . . . . . . . . . . . . . . . . . 508
Using Simplexml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
Laying the groundwork . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Chapter 16 SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Overview of SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
The SOAP envelope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
The SOAP body . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
A typical request/response pair . . . . . . . . . . . . . . . . . . . . . . . 522
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
The essence of NuSOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
A simple NuSOAP service call . . . . . . . . . . . . . . . . . . . . . . . 526
Contents xxi
Determining the Goals of the Application . . . . . . . . . . . . . 527
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
The Barnes & Noble application . . . . . . . . . . . . . . . . . . . . . . 528
The Babelfish application . . . . . . . . . . . . . . . . . . . . . . . . . . 532
Writing a SOAP server application . . . . . . . . . . . . . . . . . . . . 534
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
Chapter 17 Project Management . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
Determining the Goals of the Application . . . . . . . . . . . . . 537
Necessary pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
Designing the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
User types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
Application users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Project and task status . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Project-user mappings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
Code Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Logging in and establishing a session . . . . . . . . . . . . . . . . . . 544
Showing active projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Creating a new project . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Uploading a file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Viewing a file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Adding a user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Code Breakdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Session management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Viewing projects’ status . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
Uploading a file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
Displaying the contents of a file . . . . . . . . . . . . . . . . . . . . . . 553
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Part V Appendixes
Appendix A What’s on the CD-ROM . . . . . . . . . . . . . . . . . . . . 557
Appendix B HTML Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
Appendix C Brief Guide to MySQL/PHP Installation and
Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 571
Appendix D MySQL Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Appendix E MySQL User Administration . . . . . . . . . . . . . . . . 597
Appendix F PHP Function Reference . . . . . . . . . . . . . . . . . . . 607
Appendix G Regular Expressions Overview . . . . . . . . . . . . . . . 659
Appendix H Helpful User-Defined Functions . . . . . . . . . . . . . . 669
xxii Contents