Beginning.Ajax.with.PHP.From.Novice.to.Professional_Lee.Babin_Apress_2007
this print for content only—size & color not accurate spine = 0.638" 272 page countBOOKS FOR PROFESSIONALS BY PROFESSIONALS®Beginning Ajax with PHP: FromNovice to ProfessionalDear Reader,With the emergence of Ajax, gone are the days of clicking and waiting on theWeb. Users now have the luxury of accessing desktop-like applications from anycomputer hosting a browser and an Internet connection. Likewise, developersnow have more reason than ever to migrate their applications to an environmentthat has the potential for unlimited users.Yet despite all that Ajax promises, many web developers readily admit beingintimidated by the need to learn JavaScript (a key Ajax technology). Not toworry! I wrote this book to show PHP users how to incorporate Ajax into theirweb applications without necessarily getting bogged down in confusingJavaScript syntax. I’ve chosen to introduce the topic by way of practical examplesand real-world applications. After a rapid introduction to Ajax fundamentals,you’ll learn how to effectively use Ajax and PHP together, followed by furtherinstruction regarding dynamically updating pages using data retrieved from aMySQL database. From there, you’ll learn how to create practical Ajax-drivenfeatures such as a dynamic file upload and thumbnail-generation tools, culmi-nating in the creation of an Ajax-based photo gallery.In later chapters, I focus on other timely topics, such as web services andbuilding spatially enabled web applications using the Google Maps API. Thebook concludes with an overview of topics that will make you a more effectiveAjax developer, including a look at cross-browser issues, security, testing anddebugging, and finally, an introduction to the document object model (DOM).Lee BabinCoauthor ofPHP 5 Recipes: A Problem-Solution ApproachUS $34.99Shelve inPHPUser level:Beginner–IntermediateBabinBeginningAjax withPHPTHE EXPERT’S VOICE®IN OPEN SOURCELee BabinBeginningAjaxwith PHPFrom Novice to ProfessionalCYANMAGENTAYELLOWBLACKPANTONE 123 CVISBN 1-59059-667-6978159059667853499689253 596678www.apress.comSOURCE CODE ONLINECompanion eBookSee last page for details on $10 eBook versionforums.apress.comFOR PROFESSIONALSBY PROFESSIONALS™Join online discussions:THE APRESS ROADMAPBeginning XMLwith DOM and AjaxBeginning Google MapsApplications with PHPand AjaxBeginningPHP and MySQL 5,Second EditionBeginning Ajax with PHPAjax Patternsand Best PracticesAjax and REST RecipesPHP 5 Objects, Patterns,and PracticeCompanioneBookAvailableBuild powerful interactive web applications byharnessing the collective power of PHP and Ajax! Lee BabinBeginning Ajax with PHPFrom Novice to Professional6676FM.qxd 9/27/06 11:49 AM Page i Beginning Ajax with PHP: From Novice to ProfessionalCopyright © 2007 by Lee BabinAll rights reserved. No part of this work may be reproduced or transmitted in any form or by any means,electronic or mechanical, including photocopying, recording, or by any information storage or retrievalsystem, without the prior written permission of the copyright owner and the publisher.ISBN-13 (pbk): 978-1-59059-667-8ISBN-10 (pbk): 1-59059-667-6Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrenceof a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademarkowner, with no intention of infringement of the trademark.Lead Editor: Jason GilmoreTechnical Reviewer: Quentin ZervaasEditorial Board: Steve Anglin, Ewan Buckingham, Gary Cornell, Jason Gilmore, Jonathan Gennick,Jonathan Hassell, James Huddleston, Chris Mills, Matthew Moodie, Dominic Shakeshaft, Jim Sumser, Keir Thomas, Matt WadeProject Manager: Richard Dal PortoCopy Edit Manager: Nicole FloresCopy Editors: Damon Larson, Jennifer WhippleAssistant Production Director: Kari Brooks-CoponyProduction Editor: Laura EstermanCompositor: Dina QuanProofreader: Lori BringIndexer: John CollinArtist: April MilneCover Designer: Kurt KramesManufacturing Director: Tom DebolskiDistributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor,New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail orders-ny@springer-sbm.com, orvisit http://www.springeronline.com. For information on translations, please contact Apress directly at 2560 Ninth Street, Suite 219, Berkeley,CA 94710. Phone 510-549-5930, fax 510-549-5939, e-mail info@apress.com, or visit http://www.apress.com. The information in this book is distributed on an “as is” basis, without warranty. Although every precautionhas been taken in the preparation of this work, neither the author(s) nor Apress shall have any liability toany person or entity with respect to any loss or damage caused or alleged to be caused directly or indi-rectly by the information contained in this work. The source code for this book is available to readers at http://www.apress.com in the Source Code/Download section.6676FM.qxd 9/27/06 11:49 AM Page ii Contents at a GlanceAbout the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ixAbout the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiAcknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiiiIntroduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv■CHAPTER 1 Introducing Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1■CHAPTER 2 Ajax Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11■CHAPTER 3 PHP and Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25■CHAPTER 4 Database-Driven Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49■CHAPTER 5 Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67■CHAPTER 6 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87■CHAPTER 7 A Real-World Ajax Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101■CHAPTER 8 Ergonomic Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123■CHAPTER 9 Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135■CHAPTER 10 Spatially Enabled Web Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . 149■CHAPTER 11 Cross-Browser Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175■CHAPTER 12 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187■CHAPTER 13 Testing and Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205■CHAPTER 14 The DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235iii6676FM.qxd 9/27/06 11:49 AM Page iii 6676FM.qxd 9/27/06 11:49 AM Page iv ContentsAbout the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ixAbout the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiAcknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiiiIntroduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv■CHAPTER 1Introducing Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1From CGI to Flash to DHTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2Pros and Cons of Today’s Web Application Environment . . . . . . . . . . . . . . . 3Enter Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4Ajax Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9■CHAPTER 2Ajax Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11HTTP Request and Response Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . 11The XMLHttpRequest Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13XMLHttpRequest Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13XMLHttpRequest Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15Cross-Browser Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17Sending a Request to the Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19Basic Ajax Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24■CHAPTER 3PHP and Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Why PHP and Ajax? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Client-Driven Communication, Server-Side Processing . . . . . . . . . . . . . . . 26Basic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26Expanding and Contracting Content . . . . . . . . . . . . . . . . . . . . . . . . . . 26Auto-Complete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32Form Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41Tool Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47v6676FM.qxd 9/27/06 11:49 AM Page v ■CHAPTER 4Database-Driven Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49Introduction to MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50Connecting to MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51Querying a MySQL Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52MySQL Tips and Precautions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57Putting Ajax-Based Database Querying to Work . . . . . . . . . . . . . . . . . . . . . 58Auto-Completing Properly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60Loading the Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65■CHAPTER 5Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67Bringing in the Ajax: GET vs. POST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68Passing Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69Form Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86■CHAPTER 6Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87Uploading Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87Displaying Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91Loading Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94Dynamic Thumbnail Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99■CHAPTER 7A Real-World Ajax Application . . . . . . . . . . . . . . . . . . . . . . . . . . . 101The Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102How It Looks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111How It Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122■CHAPTER 8Ergonomic Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123When to Use Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124Back Button Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125Ajax Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125Hiding and Showing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127Introduction to PEAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128HTML_Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134■CONTENTSvi6676FM.qxd 9/27/06 11:49 AM Page vi ■CHAPTER 9Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135Introduction to SOAP Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136Bring in the Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137Let’s Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137How the SOAP Application Works . . . . . . . . . . . . . . . . . . . . . . . . . . . 142Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147■CHAPTER 10Spatially Enabled Web Applications . . . . . . . . . . . . . . . . . . . . . 149Why Is Google Maps so Popular? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149Where to Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151How Our Mapping System Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174■CHAPTER 11Cross-Browser Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175Ajax Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175Saving the Back Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177Ajax Response Concerns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180Degrading JavaScript Gracefully . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183The noscript Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184Browser Upgrades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185■CHAPTER 12Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187Increased Attack Surface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187Strategy 1: Keep Related Entry Points Within the Same Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188Strategy 2: Use Standard Functions to Process and Use User Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188Cross-Site Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189Strategy 1: Remove Unwanted Tags from Input Data . . . . . . . . . . . 191Strategy 2: Escape Tags When Outputting Client-Submitted Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192Strategy 3: Protect Your Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . 192Cross-Site Request Forgery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193Confirming Important Actions Using a One-Time Token . . . . . . . . 193Confirming Important Actions Using the User’s Password . . . . . . . 195GET vs. POST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195Accidental CSRF Attacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195■CONTENTS vii6676FM.qxd 9/27/06 11:49 AM Page vii Denial of Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196Strategy 1: Use Delays to Throttle Requests . . . . . . . . . . . . . . . . . . 197Strategy 2: Optimize Ajax Response Data . . . . . . . . . . . . . . . . . . . . 198Protecting Intellectual Property and Business Logic . . . . . . . . . . . . . . . . 200Strategy 1: JavaScript Obfuscation . . . . . . . . . . . . . . . . . . . . . . . . . . 200Strategy 2: Real-Time Server-Side Processing . . . . . . . . . . . . . . . . 201Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204■CHAPTER 13Testing and Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205JavaScript Error Reporting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205Firefox Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208Web Developer Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208The DOM Inspector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208LiveHTTPHeaders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209Venkman JavaScript Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211HTML Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212Internet Explorer Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213Internet Explorer Developer Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . 214Fiddler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216■CHAPTER 14The DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217Accessing DOM Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217document.getElementById . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217getElementsByTagName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218Accessing Elements Within a Form . . . . . . . . . . . . . . . . . . . . . . . . . . 219Adding and Removing DOM Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219Manipulating DOM Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221Manipulating XML Using the DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222Combining Ajax and XML with the DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . 223How the Ajax Location Manager Works . . . . . . . . . . . . . . . . . . . . . . . . . . . 228Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235■CONTENTSviii6676FM.qxd 9/27/06 11:49 AM Page viii About the Author■LEE BABIN is a programmer based in Calgary, Alberta, where he ownsand operates an innovative development firm duly named Code Writer.He has been developing complex web-driven applications since hisgraduation from DeVry University in early 2002, and has since workedon over 100 custom web sites and online applications. Lee is married to a beautiful woman by the name of Dianne, whosupports him in his rather full yet rewarding work schedule. Lee andDianne are currently expecting their first child, and Lee cannot wait tobe a father.Lee enjoys video games, working out, martial arts, and traveling, and can usually be foundworking online on one of his many fun web projects.ix6676FM.qxd 9/27/06 11:49 AM Page ix . of PHP and Ajax! Lee BabinBeginning Ajax with PHPFrom Novice to Professional6 676FM.qxd 9/27/06 11:49 AM Page i Beginning Ajax with PHP: From Novice to. level:Beginner–IntermediateBabinBeginningAjax withPHPTHE EXPERT’S VOICE®IN OPEN SOURCELee BabinBeginningAjaxwith PHPFrom Novice to ProfessionalCYANMAGENTAYELLOWBLACKPANTONE 123