with CSS, Ajax, and PHP
CONTENTS AT A GLANCE
Foreword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
About the Technical Reviewer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
Chapter 1: Dreamweaver CS3— . . . . . . . . . . . . . 1
Chapter 2: Building Dynamic Sites with Ajax and PHP. . . . . . . . . . . . . 33
Chapter 3: Getting the Work Environment Ready . . . . . . . . . . . . . . . . 67
Chapter 4: Setting Up a PHP Site . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Chapter 5: Adding a Touch of Style . . . . . . . . . . . . . . . . . . . . . . . . . 135
Chapter 6: Creating a CSS Site Straight Out of the Box . . . . . . . . . . . 161
Chapter 7: Building Site Navigation with the Spry Menu Bar. . . . . . . 183
Chapter 8: Sprucing Up Content with Spry Widgets . . . . . . . . . . . . . 209
Chapter 9: Building Online Forms and Validating Input. . . . . . . . . . . 247
iv
Chapter 10: Introducing the Basics of PHP . . . . . . . . . . . . . . . . . . . . 295
Chapter 11: Using PHP to Process a Form. . . . . . . . . . . . . . . . . . . . . 325
Chapter 12: Working with PHP Includes and Templates . . . . . . . . . . 363
Chapter 13: Setting Up MySQL and phpMyAdmin. . . . . . . . . . . . . . . 401
Chapter 14: Storing Records in a Database . . . . . . . . . . . . . . . . . . . . 429
Chapter 15: Controlling Access to Your Site . . . . . . . . . . . . . . . . . . . 473
Chapter 16: Working with Multiple Tables . . . . . . . . . . . . . . . . . . . . 519
Chapter 17: Searching Records and Handling Dates . . . . . . . . . . . . . 571
Chapter 18: Using XSLT to Display Live News Feeds and XML . . . . . . 617
Chapter 19: Using Spry to Display XML. . . . . . . . . . . . . . . . . . . . . . . 653
Chapter 20: Getting the Best of Both Worlds with PHP and Spry. . . . 693
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731
CONTENTS
Foreword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
About the Technical Reviewer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
Chapter 1: Dreamweaver CS3— . . . . . . . . . . . . . 1
Getting your bearings in Dreamweaver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Starting up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Creating a new document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Setting new document preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Exploring the workspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Insert bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Document window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Organizing your workspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Rearranging panels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Saving and sharing customized workspace layouts . . . . . . . . . . . . . . . . . . 14
Accessing hidden files and folders in Windows . . . . . . . . . . . . . . . . . . . . 15
Displaying optional toolbars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Temporarily hiding all panels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Organizing visual assets with Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Controlling thumbnails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Adding metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Renaming files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Dragging and dropping files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
vi
Creating standards-compliant web pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Enhanced CSS support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Layers are dead . . . Welcome, AP elements . . . . . . . . . . . . . . . . . . . . . . 18
Seeing the impact of CSS changes in real time . . . . . . . . . . . . . . . . . . . . 20
Improved style sheet management . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Using visual aids to understand your CSS structure . . . . . . . . . . . . . . . . . . 22
Checking for browser bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Checking what your page will look like on other media . . . . . . . . . . . . . . . 24
Understanding Dreamweaver’s approach to layout . . . . . . . . . . . . . . . . . . . . 25
Drawing absolutely positioned elements . . . . . . . . . . . . . . . . . . . . . . . 25
Layout Mode goes into exile. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Getting the best out of Code view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Using the Coding toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Setting Code view options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Using code hints and auto completion . . . . . . . . . . . . . . . . . . . . . . . . . 30
Dynamic too . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Chapter 2: Building Dynamic Sites with Ajax and PHP. . . . . . . . . . . . . 33
Understanding how dynamic pages work . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Making pages dynamic with client-side technology . . . . . . . . . . . . . . . . . . . . 35
Increasing user interactivity with server-side technology . . . . . . . . . . . . . . . . . 35
Why choose PHP?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Taking dynamic functionality a stage further with Ajax . . . . . . . . . . . . . . . . . . 38
Understanding the limitations of Ajax . . . . . . . . . . . . . . . . . . . . . . . . . 38
Dynamic terminology 101 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Using Dreamweaver behaviors and Spry effects . . . . . . . . . . . . . . . . . . . . . . . . 40
Accessing the Behaviors panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Giving elements a unique identity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Removing an id attribute. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Editing behavior and effect settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Removing behaviors and effects cleanly . . . . . . . . . . . . . . . . . . . . . . . . 50
Restoring a deleted behavior or effect . . . . . . . . . . . . . . . . . . . . . . . . . 50
Exploring Spry effects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Appear/Fade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Blind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Grow/Shrink. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Highlight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Shake . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Slide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Squish . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Creating a wrapper
for the Slide effect . . . . . . . . . . . . . . . . . . . . . . . 56
Applying multiple events to a trigger element . . . . . . . . . . . . . . . . . . . . . . . 58
Handling dynamic data with Spry and PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Comparing how Spry and PHP handle data sets . . . . . . . . . . . . . . . . . . . . . . 59
Building PHP sites with Dreamweaver . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
CONTENTS
vii
Comparing different versions of files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Setting up the File Compare feature . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Using File Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Comparing two local files in the same site . . . . . . . . . . . . . . . . . . . . . . . 63
Comparing two local files in different sites . . . . . . . . . . . . . . . . . . . . . . 63
Comparing local and remote files. . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Meet Mark of the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
The next step. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Chapter 3: Getting the Work Environment Ready . . . . . . . . . . . . . . . . 67
Deciding where to test your pages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Checking that your remote server supports PHP. . . . . . . . . . . . . . . . . . . . . . 69
Creating a local testing server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Choosing which versions to install. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Choosing individual installation or an all-in-one package . . . . . . . . . . . . . . . . . 71
Setting up on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Getting Windows to display file name extensions . . . . . . . . . . . . . . . . . . . 72
Choosing the right web server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Downloading the software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Preparing for installation on Windows Vista . . . . . . . . . . . . . . . . . . . . . . 73
Turning off User Account Control temporarily on Vista . . . . . . . . . . . . . . . 74
Before you begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Checking that port 80 is free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Installing Apache on Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Running the Apache Monitor on Vista . . . . . . . . . . . . . . . . . . . . . . . . . 78
Starting and stopping Apache on Windows . . . . . . . . . . . . . . . . . . . . . . 79
Changing startup preferences or disabling Apache . . . . . . . . . . . . . . . . . . 79
Installing PHP on Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Testing your PHP installation (Windows XP and Vista) . . . . . . . . . . . . . . . . 82
Changing the default Apache port . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Changing the default IIS port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Setting up on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Starting and stopping Apache on Mac OS X . . . . . . . . . . . . . . . . . . . . . . 86
Upgrading PHP on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Checking your PHP configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Understanding the output of phpinfo() . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Checking the location of php.ini . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Checking PHP Core settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Checking installed extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Checking supported $_SERVER variables. . . . . . . . . . . . . . . . . . . . . . . . 96
Editing php.ini . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Accessing php.ini on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Configuring PHP to display errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Enabling PHP extensions on Windows . . . . . . . . . . . . . . . . . . . . . . . . . 98
Enabling file uploads and sessions (Windows installer) . . . . . . . . . . . . . . . . 99
CONTENTS
viii
Overriding settings on your remote server . . . . . . . . . . . . . . . . . . . . . . . . . 99
Suppressing error messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Overriding default settings with ini_set(). . . . . . . . . . . . . . . . . . . . . . . . 99
Using .htaccess to change default settings . . . . . . . . . . . . . . . . . . . . . . 100
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Chapter 4: Setting Up a PHP Site . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Deciding where to locate your sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Understanding document- and root-relative links . . . . . . . . . . . . . . . . . . . . 104
Document-relative links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Root-relative links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Keeping everything together in the server root . . . . . . . . . . . . . . . . . . . . . 106
Working with virtual hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Finding the server root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Moving the Apache server root on Windows . . . . . . . . . . . . . . . . . . . . . . . 107
Setting a default file for Apache on Windows . . . . . . . . . . . . . . . . . . . . . . 108
Adding a default PHP file to IIS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Creating virtual hosts on Apache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Registering virtual hosts on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Registering virtual hosts on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Registering virtual directories on IIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Defining a PHP site in Dreamweaver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Opening the Site Definition dialog box . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Telling Dreamweaver where to find local files . . . . . . . . . . . . . . . . . . . . . . 117
Telling Dreamweaver how to access your remote server . . . . . . . . . . . . . . . . 119
Defining the testing server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Selecting options for local testing . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Selecting options for remote testing . . . . . . . . . . . . . . . . . . . . . . . . . 123
Setting up other site options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Setting up for Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Saving the site definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Testing your PHP site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Setting options for Preview in Browser . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Managing Dreamweaver sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Now let’s get on with it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Chapter 5: Adding a Touch of Style . . . . . . . . . . . . . . . . . . . . . . . . . 135
Avoiding bad habits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Stay away from the Property inspector for fonts . . . . . . . . . . . . . . . . . . . . . 137
Creating simple CSS for beginners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Introducing the CSS Styles panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Opening the CSS Styles panel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Viewing All and Current modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
CONTENTS
ix
Exploring the Properties pane of the CSS Styles panel . . . . . . . . . . . . . . . . . . 142
Displaying CSS properties by category . . . . . . . . . . . . . . . . . . . . . . . . 142
Displaying CSS properties alphabetically . . . . . . . . . . . . . . . . . . . . . . . 143
Displaying only CSS properties that have been set. . . . . . . . . . . . . . . . . . 143
Attaching a new style sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Adding, editing, and deleting style rules . . . . . . . . . . . . . . . . . . . . . . . 144
Creating new style rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Defining a selector. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Defining the rule’s properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Moving style rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Exporting rules to a new style sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Moving rules within a style sheet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Moving rules between external style sheets. . . . . . . . . . . . . . . . . . . . . . . . 155
Setting your CSS preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Creating and editing style rules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Setting the default format of style rules. . . . . . . . . . . . . . . . . . . . . . . . . . 158
Let’s get creative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Chapter 6: Creating a CSS Site Straight Out of the Box . . . . . . . . . . . 161
Using a built-in CSS layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Choosing a layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Deciding where to locate your style rules . . . . . . . . . . . . . . . . . . . . . . . . . 163
Linking to existing style sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Making sure conditional comments are applied . . . . . . . . . . . . . . . . . . . 164
Styling a page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Inspecting the cascade in Current mode . . . . . . . . . . . . . . . . . . . . . . . . . 173
Finishing the layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Removing the CSS comments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
How was it for you? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Chapter 7: Building Site Navigation with the Spry Menu Bar. . . . . . . 183
Examining the structure of a Spry menu bar . . . . . . . . . . . . . . . . . . . . . . . . . 185
Looking at the XHTML structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Removing a menu bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Editing a menu bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Maintaining accessibility with the Spry menu bar. . . . . . . . . . . . . . . . . . . . . 189
Customizing the styles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Changing the menu width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Changing colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Adding borders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Changing the font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Styling a Spry menu bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
To wrap or not to wrap, that is the question . . . . . . . . . . . . . . . . . . . . . . . . 193
Building the navigation structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Customizing the design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
A mixed blessing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
CONTENTS
x
Chapter 8: Sprucing Up Content with Spry Widgets . . . . . . . . . . . . . 209
Features common to all Spry widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Building a tabbed interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Examining the structure of the tabbed panels widget . . . . . . . . . . . . . . . . . . 212
Editing a tabbed panels widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Selecting harmonious colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Converting to vertical tabs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Avoiding design problems with tabbed panels . . . . . . . . . . . . . . . . . . . . . . 227
Understanding Spry objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Using the accordion widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Examining the structure of an accordion . . . . . . . . . . . . . . . . . . . . . . . . . 230
Editing and styling a Spry Accordion. . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Using the object initialization to change accordion defaults . . . . . . . . . . . . . . 236
Opening an accordion panel from a link . . . . . . . . . . . . . . . . . . . . . . . . . 238
Using collapsible panels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Examining the structure of a collapsible panel . . . . . . . . . . . . . . . . . . . . . . 239
Editing and styling collapsible panels . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Opening a collapsible panel from a link . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Removing a Spry widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Yet more widgets . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Chapter 9: Building Online Forms and Validating Input. . . . . . . . . . . 247
Building a simple feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Choosing the right page type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Creating a PHP page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Mixing .php and .html pages in a site . . . . . . . . . . . . . . . . . . . . . . . . . 250
Inserting a form in a page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Inserting a form in Code view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Adding text input elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Setting properties for text input elements . . . . . . . . . . . . . . . . . . . . . . 255
Converting a text field to a text area and vice versa. . . . . . . . . . . . . . . . . 257
Styling the basic feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Understanding the difference between GET and POST . . . . . . . . . . . . . . . . . 259
Passing information through a hidden field . . . . . . . . . . . . . . . . . . . . . . . . 260
Using multiple-choice form elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Offering a range of choices with checkboxes . . . . . . . . . . . . . . . . . . . . . . . 262
Offering a single choice from a drop-down menu . . . . . . . . . . . . . . . . . . . . 267
Creating a multiple-choice scrollable list . . . . . . . . . . . . . . . . . . . . . . . . . 269
Using radio buttons to offer a single choice . . . . . . . . . . . . . . . . . . . . . . . 272
Organizing form elements in logical groups . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Inserting a fieldset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Validating user input before submission . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Doing minimal checks with the Validate Form behavior . . . . . . . . . . . . . . . . . 275
Using Spry validation widgets for sophisticated checks . . . . . . . . . . . . . . . . . 277
Understanding the limitations of Spry validation widgets . . . . . . . . . . . . . . 278
Inserting a Spry validation widget . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Removing a validation widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Validating a text field with Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
CONTENTS
xi
Building your own custom pattern . . . . . . . . . . . . . . . . . . . . . . . . . . 285
Validating a text area with Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Validating a single checkbox with Spry . . . . . . . . . . . . . . . . . . . . . . . . 289
Validating a checkbox group with Spry . . . . . . . . . . . . . . . . . . . . . . . . 289
Validating a drop-down menu with Spry . . . . . . . . . . . . . . . . . . . . . . . 292
Next, let’s move to the server side . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Chapter 10: Introducing the Basics of PHP . . . . . . . . . . . . . . . . . . . . 295
Introducing the basics of PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Embedding PHP in a web page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Ending commands with a semicolon . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Using variables to represent changing values . . . . . . . . . . . . . . . . . . . . . . . 298
Naming variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Assigning values to variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Displaying PHP output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Commenting scripts for clarity and debugging . . . . . . . . . . . . . . . . . . . . . . 300
Choosing single or double quotation marks . . . . . . . . . . . . . . . . . . . . . . . 301
Using escape sequences in strings . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Joining strings together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Adding to an existing string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Using quotes efficiently. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Special cases: true, false and null . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Working with numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Performing calculations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Combining calculations and assignment . . . . . . . . . . . . . . . . . . . . . . . 308
Using arrays to store multiple values . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Using names to identify array elements . . . . . . . . . . . . . . . . . . . . . . . . 309
Inspecting the contents of an array with print_r() . . . . . . . . . . . . . . . . . . 310
Making decisions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
The truth according to PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Using comparisons to make decisions. . . . . . . . . . . . . . . . . . . . . . . . . 313
Testing more than one condition . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Using the switch statement for decision chains . . . . . . . . . . . . . . . . . . . 316
Using the conditional operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Using loops for repetitive tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Loops using while and do . . . while . . . . . . . . . . . . . . . . . . . . . . . . . . 317
The versatile for loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Looping through arrays with foreach . . . . . . . . . . . . . . . . . . . . . . . . . 319
Breaking out of a loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Using functions for preset tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Understanding PHP error messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Now put it to work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
CONTENTS
xii
99b97f3f1bc9631d160a36b01c7e500e
Chapter 11: Using PHP to Process a Form. . . . . . . . . . . . . . . . . . . . . 325
Activating the form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Getting information from the server with PHP superglobals . . . . . . . . . . . . . . 327
Sending email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Scripting the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Using Balance Braces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Testing the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Troubleshooting mail() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Getting rid of unwanted backslashes . . . . . . . . . . . . . . . . . . . . . . . . . 338
Making sure required fields aren’t blank . . . . . . . . . . . . . . . . . . . . . . . 341
Preserving user input when a form is incomplete . . . . . . . . . . . . . . . . . . 345
Filtering out potential attacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
Safely including the user’s address in email headers . . . . . . . . . . . . . . . . 350
Handling multiple-choice form elements . . . . . . . . . . . . . . . . . . . . . . . 354
Redirecting to another page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Time for a breather . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Chapter 12: Working with PHP Includes and Templates . . . . . . . . . . 363
Including text and code from other files. . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Introducing the PHP include commands. . . . . . . . . . . . . . . . . . . . . . . . . . 364
Telling PHP where to find the external file . . . . . . . . . . . . . . . . . . . . . . . . 365
Using site-root-relative links with includes . . . . . . . . . . . . . . . . . . . . . . . . 368
Lightening your workload with includes . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Choosing the right file name extension for include files . . . . . . . . . . . . . . 369
Displaying XHTML output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Avoiding problems with include files . . . . . . . . . . . . . . . . . . . . . . . . . 373
Applying styles with Design Time Style Sheets . . . . . . . . . . . . . . . . . . . . 374
Adding dynamic code to an include. . . . . . . . . . . . . . . . . . . . . . . . . . 375
Using includes to recycle frequently used PHP code. . . . . . . . . . . . . . . . . 378
Adapting the mail processing script as an include . . . . . . . . . . . . . . . . . . . . 380
Analyzing the script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
Building the message body with a generic script . . . . . . . . . . . . . . . . . . . 382
Avoiding the “headers already sent” error . . . . . . . . . . . . . . . . . . . . . . . . 388
Using Dreamweaver templates in a PHP site. . . . . . . . . . . . . . . . . . . . . . . . . . 389
Creating a template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Adding editable regions to the master template . . . . . . . . . . . . . . . . . . . . . 391
Creating child pages from a template . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
Locking code outside the tags. . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Choosing the right tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
CONTENTS
xiii
Chapter 13: Setting Up MySQL and phpMyAdmin. . . . . . . . . . . . . . . 401
Introducing MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
Understanding basic MySQL terminology . . . . . . . . . . . . . . . . . . . . . . . . . 403
Installing MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Installing MySQL on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Deciding whether to enable InnoDB support. . . . . . . . . . . . . . . . . . . . . 404
Changing the default table type on Windows Essentials . . . . . . . . . . . . . . . . . 410
Starting and stopping MySQL manually on Windows. . . . . . . . . . . . . . . . . . . 411
Using the MySQL monitor on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Setting up MySQL on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Adding MySQL to your PATH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
Securing MySQL on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
Using the MySQL monitor on Windows and Mac . . . . . . . . . . . . . . . . . . . . . . . 418
Using MySQL with phpMyAdmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Setting up phpMyAdmin on Windows and Mac . . . . . . . . . . . . . . . . . . . . . 420
Launching phpMyAdmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Logging out of phpMyAdmin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Backup and data transfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Looking ahead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Chapter 14: Storing Records in a Database . . . . . . . . . . . . . . . . . . . . 429
Setting up a database in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Creating a local database for testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Creating user accounts for MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Granting the necessary user privileges . . . . . . . . . . . . . . . . . . . . . . . . 432
How a database stores information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
How primary keys work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Designing a database table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Choosing the table name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Deciding how many columns to create . . . . . . . . . . . . . . . . . . . . . . . . 438
Choosing the right column type in MySQL . . . . . . . . . . . . . . . . . . . . . . 439
Deciding whether a field can be empty . . . . . . . . . . . . . . . . . . . . . . . . 441
Storing input from the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Analyzing the form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Defining a table in phpMyAdmin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Understanding collation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Inserting data from the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Troubleshooting the connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
Using server behaviors with site-root-relative links. . . . . . . . . . . . . . . . . . . . 452
Inspecting the server behavior code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Inserting data into SET columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Displaying database content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Creating a recordset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Displaying individual records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Displaying line breaks in text. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Merging form input with mail processing . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
A great deal achieved . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
CONTENTS
xiv
Chapter 15: Controlling Access to Your Site . . . . . . . . . . . . . . . . . . . 473
Creating a user registration system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
Defining the database table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
Building the registration form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
Preserving the integrity of your records . . . . . . . . . . . . . . . . . . . . . . . . . . 480
Building custom server behaviors . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
Completing the user registration form . . . . . . . . . . . . . . . . . . . . . . . . 489
Updating and deleting user records . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
Adapting the Sticky Text Field server behavior . . . . . . . . . . . . . . . . . . . . 496
Building the update and delete pages. . . . . . . . . . . . . . . . . . . . . . . . . 497
What sessions are and how they work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Creating PHP sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Creating and destroying session variables . . . . . . . . . . . . . . . . . . . . . . . . . 508
Destroying a session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
Checking that sessions are enabled . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Registering and authenticating users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Creating a login system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Restricting access to individual pages . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
Logging out users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Understanding how Dreamweaver tracks users . . . . . . . . . . . . . . . . . . . . . . 513
Creating your own $_SESSION variables from user details . . . . . . . . . . . . . 515
Redirecting to a personal page after login . . . . . . . . . . . . . . . . . . . . . . 515
Encrypting and decrypting passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
Feeling more secure? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
Chapter 16: Working with Multiple Tables . . . . . . . . . . . . . . . . . . . . 519
Storing related information in separate tables . . . . . . . . . . . . . . . . . . . . . . . . 520
Deciding on the best structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Using foreign keys to link records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
Avoiding orphaned records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Defining the database tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
Adding an index to a column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Defining the foreign key relationship in InnoDB . . . . . . . . . . . . . . . . . . . 526
Populating the tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
Restoring the content of the tables . . . . . . . . . . . . . . . . . . . . . . . . . . 530
Selecting records from more than one table . . . . . . . . . . . . . . . . . . . . . . . . . 530
The four essential SQL commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
UPDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Managing content with multiple tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Inserting new quotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
Using a MySQL function and alias to manipulate data. . . . . . . . . . . . . . . . 543
Inserting new authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Using variables in a SQL query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Updating authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
CONTENTS
xv
Deleting authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
Improving the delete form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
Performing a cascading delete with InnoDB tables . . . . . . . . . . . . . . . . . 560
Updating quotations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
Solving the mystery of missing records . . . . . . . . . . . . . . . . . . . . . . . . 564
Deleting quotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
What you have achieved. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
Chapter 17: Searching Records and Handling Dates . . . . . . . . . . . . . 571
Querying a database and displaying the results . . . . . . . . . . . . . . . . . . . . . . . . 572
Enhancing the look of search results. . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
Displaying the number of search results . . . . . . . . . . . . . . . . . . . . . . . 573
Creating striped table rows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
Understanding how Dreamweaver builds a SQL query. . . . . . . . . . . . . . . . . . 576
Troubleshooting SQL queries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
Setting search criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
Using numerical comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Searching within a numerical range . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Searching for text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
Making a search case sensitive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
Displaying a message when no results are found . . . . . . . . . . . . . . . . . . 587
Searching multiple columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
Searching with a partial match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
Using wildcard characters in a search . . . . . . . . . . . . . . . . . . . . . . . . . 589
Using wildcard characters with numbers . . . . . . . . . . . . . . . . . . . . . . . 592
Using a FULLTEXT index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
Solving common problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Counting records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Eliminating duplicates from a recordset . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Reusing a recordset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Understanding how a repeat region works . . . . . . . . . . . . . . . . . . . . . . 602
Formatting dates and time in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
Using DATE_FORMAT() to output user-friendly dates . . . . . . . . . . . . . . . . . . 604
Working with dates in PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
Setting the correct time zone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
Creating a Unix timestamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609
Formatting dates in PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 610
Storing dates in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
Validating and formatting dates for database input . . . . . . . . . . . . . . . . . . . 612
Continuing the search for perfection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615
Chapter 18: Using XSLT to Display Live News Feeds and XML . . . . . . 617
A quick guide to XML and XSLT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
What an XML document looks like. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
Using HTML entities in XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620
Using XSLT to display XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
Checking your server’s support for XSLT . . . . . . . . . . . . . . . . . . . . . . . 621
CONTENTS
xvi
Pulling in an RSS news feed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622
How Dreamweaver handles server-side XSLT . . . . . . . . . . . . . . . . . . . . . . . 623
Using XSLT to access the XML source data . . . . . . . . . . . . . . . . . . . . . . . . 624
Displaying the news feed in a web page. . . . . . . . . . . . . . . . . . . . . . . . . . 632
Being a bit more adventurous with XSLT. . . . . . . . . . . . . . . . . . . . . . . . . . . . 633
Setting up a local XML source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
Understanding how XSLT is structured . . . . . . . . . . . . . . . . . . . . . . . . . . 636
Accessing nested repeating elements . . . . . . . . . . . . . . . . . . . . . . . . . . . 637
Creating conditional regions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639
Testing a single condition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639
Testing alternative conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640
Sorting elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642
Formatting elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643
Displaying output selectively . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Filtering nodes with XPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Using XSLT parameters to filter data . . . . . . . . . . . . . . . . . . . . . . . . . 646
More XML to come . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
Chapter 19: Using Spry to Display XML. . . . . . . . . . . . . . . . . . . . . . . 653
How Spry handles XML data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654
Making sure Spry can find data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
Creating a Spry data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656
Displaying a data set in a Spry table . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
Understanding the Spry data code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
Validating pages that use Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
The fly in Spry’s ointment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669
Displaying a data set as a list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
What’s the difference between repeat and repeatchildren? . . . . . . . . . . . . 674
Case study: Building a Spry image gallery . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
Planning the gallery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
Dynamically selecting the gallery data set . . . . . . . . . . . . . . . . . . . . . . 677
Controlling the structure with CSS. . . . . . . . . . . . . . . . . . . . . . . . . . . 677
Putting everything together. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 678
Activating the event handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
Distinguishing between data sets . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
Creating a data set dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
Nearly there . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
Chapter 20: Getting the Best of Both Worlds with PHP and Spry. . . . 693
Generating XML dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694
Preparing the database table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695
Using phpMyAdmin to generate XML . . . . . . . . . . . . . . . . . . . . . . . . . . . 696
Using the XML Export extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
Updating the includes folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
Building XML manually from a recordset . . . . . . . . . . . . . . . . . . . . . . . . . 703
Using a proxy script to fetch a remote feed . . . . . . . . . . . . . . . . . . . . . . . 706
CONTENTS
xvii
Creating an XML document from a dynamic source . . . . . . . . . . . . . . . . . . . 707
Setting permission for PHP to write files . . . . . . . . . . . . . . . . . . . . . . . 708
Using PHP to write to a file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708
Using Spry in pages that work without JavaScript . . . . . . . . . . . . . . . . . . . . . . . 711
How to incorporate a Spry data set in an ordinary web page . . . . . . . . . . . . . . 711
Using XHTML with Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716
Case study: Making the Spry gallery accessible . . . . . . . . . . . . . . . . . . . . . . . . 717
Creating the gallery with PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
Generating the XML sources with PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . 725
Enhancing the accessible gallery with Spry . . . . . . . . . . . . . . . . . . . . . . . . 727
The end of a long journey . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731
CONTENTS
Applying multiple events to a trigger element . . . . . . . . . . . . . . . . . . . . . . . 58
Handling dynamic data with Spry and PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Comparing how Spry and PHP handle data sets . . . . . . . . . . . . . . . . . . . . . . 59
Building PHP sites with Dreamweaver . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
CONTENTS
vii
Comparing different versions of files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Setting up the File Compare feature . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Using File Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Comparing two local files in the same site . . . . . . . . . . . . . . . . . . . . . . . 63
Comparing two local files in different sites . . . . . . . . . . . . . . . . . . . . . . 63
Comparing local and remote files. . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Meet Mark of the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
The next step. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Chapter 3: Getting the Work Environment Ready . . . . . . . . . . . . . . . . 67
Deciding where to test your pages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Checking that your remote server supports PHP. . . . . . . . . . . . . . . . . . . . . . 69
Creating a local testing server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Choosing which versions to install. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Choosing individual installation or an all-in-one package . . . . . . . . . . . . . . . . . 71
Setting up on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Getting Windows to display file name extensions . . . . . . . . . . . . . . . . . . . 72
Choosing the right web server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Downloading the software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Preparing for installation on Windows Vista . . . . . . . . . . . . . . . . . . . . . . 73
Turning off User Account Control temporarily on Vista . . . . . . . . . . . . . . . 74
Before you begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Checking that port 80 is free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Installing Apache on Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Running the Apache Monitor on Vista . . . . . . . . . . . . . . . . . . . . . . . . . 78
Starting and stopping Apache on Windows . . . . . . . . . . . . . . . . . . . . . . 79
Changing startup preferences or disabling Apache . . . . . . . . . . . . . . . . . . 79
Installing PHP on Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Testing your PHP installation (Windows XP and Vista) . . . . . . . . . . . . . . . . 82
Changing the default Apache port . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Changing the default IIS port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Setting up on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Starting and stopping Apache on Mac OS X . . . . . . . . . . . . . . . . . . . . . . 86
Upgrading PHP on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Checking your PHP configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Understanding the output of phpinfo() . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Checking the location of php.ini . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Checking PHP Core settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Checking installed extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Checking supported $_SERVER variables. . . . . . . . . . . . . . . . . . . . . . . . 96
Editing php.ini . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Accessing php.ini on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Configuring PHP to display errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Enabling PHP extensions on Windows . . . . . . . . . . . . . . . . . . . . . . . . . 98
Enabling file uploads and sessions (Windows installer) . . . . . . . . . . . . . . . . 99
CONTENTS
viii
Overriding settings on your remote server . . . . . . . . . . . . . . . . . . . . . . . . . 99
Suppressing error messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Overriding default settings with ini_set(). . . . . . . . . . . . . . . . . . . . . . . . 99
Using .htaccess to change default settings . . . . . . . . . . . . . . . . . . . . . . 100
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Chapter 4: Setting Up a PHP Site . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Deciding where to locate your sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Understanding document- and root-relative links . . . . . . . . . . . . . . . . . . . . 104
Document-relative links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Root-relative links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Keeping everything together in the server root . . . . . . . . . . . . . . . . . . . . . 106
Working with virtual hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Finding the server root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Moving the Apache server root on Windows . . . . . . . . . . . . . . . . . . . . . . . 107
Setting a default file for Apache on Windows . . . . . . . . . . . . . . . . . . . . . . 108
Adding a default PHP file to IIS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Creating virtual hosts on Apache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Registering virtual hosts on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Registering virtual hosts on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Registering virtual directories on IIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Defining a PHP site in Dreamweaver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Opening the Site Definition dialog box . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Telling Dreamweaver where to find local files . . . . . . . . . . . . . . . . . . . . . . 117
Telling Dreamweaver how to access your remote server . . . . . . . . . . . . . . . . 119
Defining the testing server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Selecting options for local testing . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Selecting options for remote testing . . . . . . . . . . . . . . . . . . . . . . . . . 123
Setting up other site options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Setting up for Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Saving the site definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Testing your PHP site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Setting options for Preview in Browser . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Managing Dreamweaver sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Now let’s get on with it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Chapter 5: Adding a Touch of Style . . . . . . . . . . . . . . . . . . . . . . . . . 135
Avoiding bad habits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Stay away from the Property inspector for fonts . . . . . . . . . . . . . . . . . . . . . 137
Creating simple CSS for beginners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Introducing the CSS Styles panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Opening the CSS Styles panel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Viewing All and Current modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
CONTENTS
ix
Exploring the Properties pane of the CSS Styles panel . . . . . . . . . . . . . . . . . . 142
Displaying CSS properties by category . . . . . . . . . . . . . . . . . . . . . . . . 142
Displaying CSS properties alphabetically . . . . . . . . . . . . . . . . . . . . . . . 143
Displaying only CSS properties that have been set. . . . . . . . . . . . . . . . . . 143
Attaching a new style sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Adding, editing, and deleting style rules . . . . . . . . . . . . . . . . . . . . . . . 144
Creating new style rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Defining a selector. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Defining the rule’s properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Moving style rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Exporting rules to a new style sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Moving rules within a style sheet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Moving rules between external style sheets. . . . . . . . . . . . . . . . . . . . . . . . 155
Setting your CSS preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Creating and editing style rules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Setting the default format of style rules. . . . . . . . . . . . . . . . . . . . . . . . . . 158
Let’s get creative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Chapter 6: Creating a CSS Site Straight Out of the Box . . . . . . . . . . . 161
Using a built-in CSS layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Choosing a layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Deciding where to locate your style rules . . . . . . . . . . . . . . . . . . . . . . . . . 163
Linking to existing style sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Making sure conditional comments are applied . . . . . . . . . . . . . . . . . . . 164
Styling a page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Inspecting the cascade in Current mode . . . . . . . . . . . . . . . . . . . . . . . . . 173
Finishing the layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Removing the CSS comments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
How was it for you? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Chapter 7: Building Site Navigation with the Spry Menu Bar. . . . . . . 183
Examining the structure of a Spry menu bar . . . . . . . . . . . . . . . . . . . . . . . . . 185
Looking at the XHTML structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Removing a menu bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Editing a menu bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Maintaining accessibility with the Spry menu bar. . . . . . . . . . . . . . . . . . . . . 189
Customizing the styles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Changing the menu width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Changing colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Adding borders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Changing the font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Styling a Spry menu bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
To wrap or not to wrap, that is the question . . . . . . . . . . . . . . . . . . . . . . . . 193
Building the navigation structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Customizing the design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
A mixed blessing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
CONTENTS
x
Chapter 8: Sprucing Up Content with Spry Widgets . . . . . . . . . . . . . 209
Features common to all Spry widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Building a tabbed interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Examining the structure of the tabbed panels widget . . . . . . . . . . . . . . . . . . 212
Editing a tabbed panels widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Selecting harmonious colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Converting to vertical tabs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Avoiding design problems with tabbed panels . . . . . . . . . . . . . . . . . . . . . . 227
Understanding Spry objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Using the accordion widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Examining the structure of an accordion . . . . . . . . . . . . . . . . . . . . . . . . . 230
Editing and styling a Spry Accordion. . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Using the object initialization to change accordion defaults . . . . . . . . . . . . . . 236
Opening an accordion panel from a link . . . . . . . . . . . . . . . . . . . . . . . . . 238
Using collapsible panels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Examining the structure of a collapsible panel . . . . . . . . . . . . . . . . . . . . . . 239
Editing and styling collapsible panels . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Opening a collapsible panel from a link . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Removing a Spry widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Yet more widgets . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Chapter 9: Building Online Forms and Validating Input. . . . . . . . . . . 247
Building a simple feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Choosing the right page type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Creating a PHP page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Mixing .php and .html pages in a site . . . . . . . . . . . . . . . . . . . . . . . . . 250
Inserting a form in a page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Inserting a form in Code view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Adding text input elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Setting properties for text input elements . . . . . . . . . . . . . . . . . . . . . . 255
Converting a text field to a text area and vice versa. . . . . . . . . . . . . . . . . 257
Styling the basic feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Understanding the difference between GET and POST . . . . . . . . . . . . . . . . . 259
Passing information through a hidden field . . . . . . . . . . . . . . . . . . . . . . . . 260
Using multiple-choice form elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Offering a range of choices with checkboxes . . . . . . . . . . . . . . . . . . . . . . . 262
Offering a single choice from a drop-down menu . . . . . . . . . . . . . . . . . . . . 267
Creating a multiple-choice scrollable list . . . . . . . . . . . . . . . . . . . . . . . . . 269
Using radio buttons to offer a single choice . . . . . . . . . . . . . . . . . . . . . . . 272
Organizing form elements in logical groups . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Inserting a fieldset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Validating user input before submission . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Doing minimal checks with the Validate Form behavior . . . . . . . . . . . . . . . . . 275
Using Spry validation widgets for sophisticated checks . . . . . . . . . . . . . . . . . 277
Understanding the limitations of Spry validation widgets . . . . . . . . . . . . . . 278
Inserting a Spry validation widget . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Removing a validation widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Validating a text field with Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
CONTENTS
xi
Building your own custom pattern . . . . . . . . . . . . . . . . . . . . . . . . . . 285
Validating a text area with Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Validating a single checkbox with Spry . . . . . . . . . . . . . . . . . . . . . . . . 289
Validating a checkbox group with Spry . . . . . . . . . . . . . . . . . . . . . . . . 289
Validating a drop-down menu with Spry . . . . . . . . . . . . . . . . . . . . . . . 292
Next, let’s move to the server side . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Chapter 10: Introducing the Basics of PHP . . . . . . . . . . . . . . . . . . . . 295
Introducing the basics of PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Embedding PHP in a web page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Ending commands with a semicolon . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Using variables to represent changing values . . . . . . . . . . . . . . . . . . . . . . . 298
Naming variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Assigning values to variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Displaying PHP output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Commenting scripts for clarity and debugging . . . . . . . . . . . . . . . . . . . . . . 300
Choosing single or double quotation marks . . . . . . . . . . . . . . . . . . . . . . . 301
Using escape sequences in strings . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Joining strings together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Adding to an existing string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Using quotes efficiently. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Special cases: true, false and null . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Working with numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Performing calculations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Combining calculations and assignment . . . . . . . . . . . . . . . . . . . . . . . 308
Using arrays to store multiple values . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Using names to identify array elements . . . . . . . . . . . . . . . . . . . . . . . . 309
Inspecting the contents of an array with print_r() . . . . . . . . . . . . . . . . . . 310
Making decisions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
The truth according to PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Using comparisons to make decisions. . . . . . . . . . . . . . . . . . . . . . . . . 313
Testing more than one condition . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Using the switch statement for decision chains . . . . . . . . . . . . . . . . . . . 316
Using the conditional operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Using loops for repetitive tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Loops using while and do . . . while . . . . . . . . . . . . . . . . . . . . . . . . . . 317
The versatile for loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Looping through arrays with foreach . . . . . . . . . . . . . . . . . . . . . . . . . 319
Breaking out of a loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Using functions for preset tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Understanding PHP error messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Now put it to work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
CONTENTS
xii
99b97f3f1bc9631d160a36b01c7e500e
Chapter 11: Using PHP to Process a Form. . . . . . . . . . . . . . . . . . . . . 325
Activating the form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Getting information from the server with PHP superglobals . . . . . . . . . . . . . . 327
Sending email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Scripting the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Using Balance Braces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Testing the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Troubleshooting mail() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Getting rid of unwanted backslashes . . . . . . . . . . . . . . . . . . . . . . . . . 338
Making sure required fields aren’t blank . . . . . . . . . . . . . . . . . . . . . . . 341
Preserving user input when a form is incomplete . . . . . . . . . . . . . . . . . . 345
Filtering out potential attacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
Safely including the user’s address in email headers . . . . . . . . . . . . . . . . 350
Handling multiple-choice form elements . . . . . . . . . . . . . . . . . . . . . . . 354
Redirecting to another page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Time for a breather . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Chapter 12: Working with PHP Includes and Templates . . . . . . . . . . 363
Including text and code from other files. . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Introducing the PHP include commands. . . . . . . . . . . . . . . . . . . . . . . . . . 364
Telling PHP where to find the external file . . . . . . . . . . . . . . . . . . . . . . . . 365
Using site-root-relative links with includes . . . . . . . . . . . . . . . . . . . . . . . . 368
Lightening your workload with includes . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Choosing the right file name extension for include files . . . . . . . . . . . . . . 369
Displaying XHTML output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Avoiding problems with include files . . . . . . . . . . . . . . . . . . . . . . . . . 373
Applying styles with Design Time Style Sheets . . . . . . . . . . . . . . . . . . . . 374
Adding dynamic code to an include. . . . . . . . . . . . . . . . . . . . . . . . . . 375
Using includes to recycle frequently used PHP code. . . . . . . . . . . . . . . . . 378
Adapting the mail processing script as an include . . . . . . . . . . . . . . . . . . . . 380
Analyzing the script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
Building the message body with a generic script . . . . . . . . . . . . . . . . . . . 382
Avoiding the “headers already sent” error . . . . . . . . . . . . . . . . . . . . . . . . 388
Using Dreamweaver templates in a PHP site. . . . . . . . . . . . . . . . . . . . . . . . . . 389
Creating a template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Adding editable regions to the master template . . . . . . . . . . . . . . . . . . . . . 391
Creating child pages from a template . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
Locking code outside the tags. . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Choosing the right tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
CONTENTS
xiii
Chapter 13: Setting Up MySQL and phpMyAdmin. . . . . . . . . . . . . . . 401
Introducing MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
Understanding basic MySQL terminology . . . . . . . . . . . . . . . . . . . . . . . . . 403
Installing MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Installing MySQL on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Deciding whether to enable InnoDB support. . . . . . . . . . . . . . . . . . . . . 404
Changing the default table type on Windows Essentials . . . . . . . . . . . . . . . . . 410
Starting and stopping MySQL manually on Windows. . . . . . . . . . . . . . . . . . . 411
Using the MySQL monitor on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Setting up MySQL on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Adding MySQL to your PATH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
Securing MySQL on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
Using the MySQL monitor on Windows and Mac . . . . . . . . . . . . . . . . . . . . . . . 418
Using MySQL with phpMyAdmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Setting up phpMyAdmin on Windows and Mac . . . . . . . . . . . . . . . . . . . . . 420
Launching phpMyAdmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Logging out of phpMyAdmin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Backup and data transfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Looking ahead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Chapter 14: Storing Records in a Database . . . . . . . . . . . . . . . . . . . . 429
Setting up a database in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Creating a local database for testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Creating user accounts for MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Granting the necessary user privileges . . . . . . . . . . . . . . . . . . . . . . . . 432
How a database stores information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
How primary keys work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Designing a database table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Choosing the table name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Deciding how many columns to create . . . . . . . . . . . . . . . . . . . . . . . . 438
Choosing the right column type in MySQL . . . . . . . . . . . . . . . . . . . . . . 439
Deciding whether a field can be empty . . . . . . . . . . . . . . . . . . . . . . . . 441
Storing input from the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Analyzing the form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Defining a table in phpMyAdmin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Understanding collation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Inserting data from the feedback form . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Troubleshooting the connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
Using server behaviors with site-root-relative links. . . . . . . . . . . . . . . . . . . . 452
Inspecting the server behavior code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Inserting data into SET columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Displaying database content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Creating a recordset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Displaying individual records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Displaying line breaks in text. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Merging form input with mail processing . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
A great deal achieved . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
CONTENTS
xiv
Chapter 15: Controlling Access to Your Site . . . . . . . . . . . . . . . . . . . 473
Creating a user registration system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
Defining the database table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
Building the registration form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
Preserving the integrity of your records . . . . . . . . . . . . . . . . . . . . . . . . . . 480
Building custom server behaviors . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
Completing the user registration form . . . . . . . . . . . . . . . . . . . . . . . . 489
Updating and deleting user records . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
Adapting the Sticky Text Field server behavior . . . . . . . . . . . . . . . . . . . . 496
Building the update and delete pages. . . . . . . . . . . . . . . . . . . . . . . . . 497
What sessions are and how they work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Creating PHP sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Creating and destroying session variables . . . . . . . . . . . . . . . . . . . . . . . . . 508
Destroying a session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
Checking that sessions are enabled . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Registering and authenticating users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Creating a login system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Restricting access to individual pages . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
Logging out users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Understanding how Dreamweaver tracks users . . . . . . . . . . . . . . . . . . . . . . 513
Creating your own $_SESSION variables from user details . . . . . . . . . . . . . 515
Redirecting to a personal page after login . . . . . . . . . . . . . . . . . . . . . . 515
Encrypting and decrypting passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
Feeling more secure? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
Chapter 16: Working with Multiple Tables . . . . . . . . . . . . . . . . . . . . 519
Storing related information in separate tables . . . . . . . . . . . . . . . . . . . . . . . . 520
Deciding on the best structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Using foreign keys to link records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
Avoiding orphaned records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Defining the database tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
Adding an index to a column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Defining the foreign key relationship in InnoDB . . . . . . . . . . . . . . . . . . . 526
Populating the tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
Restoring the content of the tables . . . . . . . . . . . . . . . . . . . . . . . . . . 530
Selecting records from more than one table . . . . . . . . . . . . . . . . . . . . . . . . . 530
The four essential SQL commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
UPDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Managing content with multiple tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Inserting new quotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
Using a MySQL function and alias to manipulate data. . . . . . . . . . . . . . . . 543
Inserting new authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Using variables in a SQL query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Updating authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
CONTENTS
xv
Deleting authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
Improving the delete form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
Performing a cascading delete with InnoDB tables . . . . . . . . . . . . . . . . . 560
Updating quotations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
Solving the mystery of missing records . . . . . . . . . . . . . . . . . . . . . . . . 564
Deleting quotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
What you have achieved. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
Chapter 17: Searching Records and Handling Dates . . . . . . . . . . . . . 571
Querying a database and displaying the results . . . . . . . . . . . . . . . . . . . . . . . . 572
Enhancing the look of search results. . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
Displaying the number of search results . . . . . . . . . . . . . . . . . . . . . . . 573
Creating striped table rows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
Understanding how Dreamweaver builds a SQL query. . . . . . . . . . . . . . . . . . 576
Troubleshooting SQL queries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
Setting search criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
Using numerical comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Searching within a numerical range . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Searching for text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
Making a search case sensitive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
Displaying a message when no results are found . . . . . . . . . . . . . . . . . . 587
Searching multiple columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
Searching with a partial match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
Using wildcard characters in a search . . . . . . . . . . . . . . . . . . . . . . . . . 589
Using wildcard characters with numbers . . . . . . . . . . . . . . . . . . . . . . . 592
Using a FULLTEXT index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
Solving common problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Counting records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Eliminating duplicates from a recordset . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Reusing a recordset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Understanding how a repeat region works . . . . . . . . . . . . . . . . . . . . . . 602
Formatting dates and time in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
Using DATE_FORMAT() to output user-friendly dates . . . . . . . . . . . . . . . . . . 604
Working with dates in PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
Setting the correct time zone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
Creating a Unix timestamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609
Formatting dates in PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 610
Storing dates in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
Validating and formatting dates for database input . . . . . . . . . . . . . . . . . . . 612
Continuing the search for perfection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615
Chapter 18: Using XSLT to Display Live News Feeds and XML . . . . . . 617
A quick guide to XML and XSLT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
What an XML document looks like. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
Using HTML entities in XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620
Using XSLT to display XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
Checking your server’s support for XSLT . . . . . . . . . . . . . . . . . . . . . . . 621
CONTENTS
xvi
Pulling in an RSS news feed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622
How Dreamweaver handles server-side XSLT . . . . . . . . . . . . . . . . . . . . . . . 623
Using XSLT to access the XML source data . . . . . . . . . . . . . . . . . . . . . . . . 624
Displaying the news feed in a web page. . . . . . . . . . . . . . . . . . . . . . . . . . 632
Being a bit more adventurous with XSLT. . . . . . . . . . . . . . . . . . . . . . . . . . . . 633
Setting up a local XML source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
Understanding how XSLT is structured . . . . . . . . . . . . . . . . . . . . . . . . . . 636
Accessing nested repeating elements . . . . . . . . . . . . . . . . . . . . . . . . . . . 637
Creating conditional regions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639
Testing a single condition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639
Testing alternative conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640
Sorting elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642
Formatting elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643
Displaying output selectively . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Filtering nodes with XPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Using XSLT parameters to filter data . . . . . . . . . . . . . . . . . . . . . . . . . 646
More XML to come . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
Chapter 19: Using Spry to Display XML. . . . . . . . . . . . . . . . . . . . . . . 653
How Spry handles XML data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654
Making sure Spry can find data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
Creating a Spry data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656
Displaying a data set in a Spry table . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
Understanding the Spry data code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
Validating pages that use Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
The fly in Spry’s ointment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669
Displaying a data set as a list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
What’s the difference between repeat and repeatchildren? . . . . . . . . . . . . 674
Case study: Building a Spry image gallery . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
Planning the gallery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
Dynamically selecting the gallery data set . . . . . . . . . . . . . . . . . . . . . . 677
Controlling the structure with CSS. . . . . . . . . . . . . . . . . . . . . . . . . . . 677
Putting everything together. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 678
Activating the event handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
Distinguishing between data sets . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
Creating a data set dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
Nearly there . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
Chapter 20: Getting the Best of Both Worlds with PHP and Spry. . . . 693
Generating XML dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694
Preparing the database table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695
Using phpMyAdmin to generate XML . . . . . . . . . . . . . . . . . . . . . . . . . . . 696
Using the XML Export extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
Updating the includes folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
Building XML manually from a recordset . . . . . . . . . . . . . . . . . . . . . . . . . 703
Using a proxy script to fetch a remote feed . . . . . . . . . . . . . . . . . . . . . . . 706
CONTENTS
xvii
Creating an XML document from a dynamic source . . . . . . . . . . . . . . . . . . . 707
Setting permission for PHP to write files . . . . . . . . . . . . . . . . . . . . . . . 708
Using PHP to write to a file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708
Using Spry in pages that work without JavaScript . . . . . . . . . . . . . . . . . . . . . . . 711
How to incorporate a Spry data set in an ordinary web page . . . . . . . . . . . . . . 711
Using XHTML with Spry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716
Case study: Making the Spry gallery accessible . . . . . . . . . . . . . . . . . . . . . . . . 717
Creating the gallery with PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
Generating the XML sources with PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . 725
Enhancing the accessible gallery with Spry . . . . . . . . . . . . . . . . . . . . . . . . 727
The end of a long journey . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731
CONTENTS
No comments:
Post a Comment