Intro |
|
xxvii | |
Who is this book for? |
|
xxviii | |
We know what you're thinking |
|
xxix | |
Metacognition |
|
xxxi | |
Bend your brain into submission |
|
xxxiii | |
Read me |
|
xxxiv | |
The technical review team |
|
xxxvi | |
Acknowledgments |
|
xxxvii | |
|
It's Alive: Add Life to Your Static Pages |
|
|
1 | (58) |
|
HTML is static and boring |
|
|
2 | (1) |
|
PHP brings web pages to life |
|
|
3 | (2) |
|
A form helps Owen get the whole story |
|
|
5 | (1) |
|
|
6 | (2) |
|
The HTML form has problems |
|
|
8 | (2) |
|
|
10 | (1) |
|
|
11 | (1) |
|
PHP scripts run on the server |
|
|
12 | (4) |
|
Use PHP to access the form data |
|
|
16 | (2) |
|
PHP scripts must live on a server! |
|
|
18 | (4) |
|
The server turns PHP into HTML |
|
|
22 | (3) |
|
A few PHP rules to code by |
|
|
25 | (1) |
|
Finding the perfect variable name |
|
|
26 | (5) |
|
Variables are for storing script data |
|
|
31 | (2) |
|
POST is a special variable that holds form data |
|
|
33 | (1) |
|
POST transports form data to your script |
|
|
34 | (10) |
|
Creating the email message body with PH P |
|
|
44 | (2) |
|
Even plain text can be formatted... a little |
|
|
46 | (1) |
|
Newlines need double-quoted strings |
|
|
47 | (1) |
|
Assemble an email message for Owen |
|
|
48 | (1) |
|
Variables store the email pieces and parts |
|
|
49 | (1) |
|
Sending an email message with PHP |
|
|
50 | (3) |
|
Owen starts getting emails |
|
|
53 | (1) |
|
Owen starts losing emails |
|
|
54 | (5) |
|
How It Fits Together: Connecting to MySQL |
|
|
59 | (44) |
|
Owen's PHP form works well. Too well |
|
|
60 | (1) |
|
MySQL excels at storing data |
|
|
61 | (1) |
|
Owen needs a MySQL database |
|
|
62 | (2) |
|
Create a MySQL database and table |
|
|
64 | (3) |
|
The INSERT statement in action |
|
|
67 | (3) |
|
Use SELECT to get table data |
|
|
70 | (3) |
|
Let PHP handle the tedious SQL stuff |
|
|
73 | (1) |
|
PHP lets data drive Owen's web form |
|
|
74 | (2) |
|
Connect to your database from PHP |
|
|
76 | (1) |
|
Insert data with a PHP script |
|
|
77 | (1) |
|
Use PHP functions to talk to the database |
|
|
78 | (2) |
|
Get connected with mysqli_connect() |
|
|
80 | (5) |
|
Build the INSERT query in PHP |
|
|
85 | (1) |
|
Query the MySQL database with PHP |
|
|
86 | (1) |
|
Close your connection with mysqli---close() |
|
|
87 | (4) |
|
POST provides the form data |
|
|
91 | (5) |
|
Owen needs help sifting through his data |
|
|
96 | (2) |
|
Owen's on his way to finding Fang |
|
|
98 | (5) |
|
Creating Your Own Data: Create and Populate a Database |
|
|
103 | (56) |
|
The Elvis store is open for business |
|
|
104 | (1) |
|
Elmer needs an application |
|
|
105 | (1) |
|
Visualize Elmer's application design |
|
|
106 | (3) |
|
It all starts with a table |
|
|
109 | (1) |
|
Make contact with the MySQL server |
|
|
110 | (1) |
|
Create a database for Elmer's emails |
|
|
111 | (1) |
|
Create a table inside the database |
|
|
112 | (1) |
|
We need to define our data |
|
|
113 | (1) |
|
Take a meeting with some MySQL data types |
|
|
114 | (3) |
|
Create your table with a query |
|
|
117 | (3) |
|
USE the database before you use it |
|
|
120 | (3) |
|
DESCRIBE reveals the structure of tables |
|
|
123 | (2) |
|
Elmer's ready to store data |
|
|
125 | (1) |
|
Create the Add Email script |
|
|
126 | (7) |
|
The other side of Elmer's application |
|
|
133 | (1) |
|
The nuts and bolts of the Send Email script |
|
|
134 | (1) |
|
First things first, grab the data |
|
|
135 | (1) |
|
mysqli_fetch_array() fetches query results |
|
|
136 | (3) |
|
|
139 | (1) |
|
Looping through data with while |
|
|
140 | (5) |
|
You've got mail...from Elmer! |
|
|
145 | (1) |
|
Sometimes people want out |
|
|
146 | (1) |
|
Removing data with DELETE |
|
|
147 | (1) |
|
Use WHERE to DELETE specific data |
|
|
148 | (1) |
|
Minimize the risk of accidental deletions |
|
|
149 | (5) |
|
MakeMeElvis.com is a web application |
|
|
154 | (5) |
|
Your Application on the Web: Realistic and Practical Applications |
|
|
159 | (64) |
|
Elmer has some irritated customers |
|
|
160 | (3) |
|
Protecting Elmer from...Elmer |
|
|
163 | (1) |
|
|
164 | (1) |
|
The logic behind Send Email validation |
|
|
165 | (1) |
|
Your code can make decisions with IF |
|
|
166 | (1) |
|
|
167 | (1) |
|
IF checks for more than just equality |
|
|
168 | (3) |
|
The logic behind Send Email validation |
|
|
171 | (1) |
|
PHP functions for verifying variables |
|
|
172 | (7) |
|
Test multiple conditions with AND and OR |
|
|
179 | (4) |
|
|
183 | (10) |
|
Ease in and out of PHP as needed |
|
|
193 | (1) |
|
Use a flag to avoid duplicate code |
|
|
194 | (1) |
|
Code the HTML form only once |
|
|
195 | (4) |
|
A form that references itself |
|
|
199 | (1) |
|
Point the form action at the script |
|
|
200 | (2) |
|
Check to see if the form has been submitted |
|
|
202 | (4) |
|
Some users are still disgruntled |
|
|
206 | (2) |
|
Table rows should be uniquely identifiable |
|
|
208 | (2) |
|
Primary keys enforce uniqueness |
|
|
210 | (5) |
|
From checkboxes to customer IDs |
|
|
215 | (1) |
|
Loop through an array with foreach |
|
|
216 | (7) |
|
When a Database Just Isn't Enough: Working With Data Stored in Files |
|
|
223 | (72) |
|
Virtual guitarists like to compete |
|
|
224 | (1) |
|
The proof is in the picture |
|
|
225 | (1) |
|
The application needs to store images |
|
|
226 | (5) |
|
Planning for image file uploads in Guitar Wars |
|
|
231 | (1) |
|
The high score database must be ALTERed |
|
|
232 | (4) |
|
How do we get an image from the user? |
|
|
236 | (2) |
|
Insert the image filename into the database |
|
|
238 | (1) |
|
Find out the name of the uploaded file |
|
|
239 | (5) |
|
Where did the uploaded file go? |
|
|
244 | (4) |
|
Create a home for uploaded image files |
|
|
248 | (6) |
|
Shared data has to be shared |
|
|
254 | (1) |
|
Shared script data is required |
|
|
255 | (1) |
|
Think of require_once as ``insert'' |
|
|
256 | (2) |
|
Order is everything with high scores |
|
|
258 | (3) |
|
Honoring the top Guitar Warrior |
|
|
261 | (1) |
|
Format the top score with HTML and CSS |
|
|
262 | (5) |
|
Only small images allowed |
|
|
267 | (1) |
|
File validation makes the app more robust |
|
|
268 | (4) |
|
|
272 | (3) |
|
Generate score removal links on the Admin page |
|
|
275 | (1) |
|
Scripts can communicate with each other |
|
|
276 | (2) |
|
|
278 | (2) |
|
GET, POST, and high score removal |
|
|
280 | (3) |
|
Isolate the high score for deletion |
|
|
283 | (1) |
|
Control how much you delete with LIMIT |
|
|
284 | (11) |
|
Assume They're All Out to Get You: Securing Your Application |
|
|
295 | (50) |
|
|
296 | (1) |
|
Where did the high scores go? |
|
|
297 | (2) |
|
Securing the teeming hordes |
|
|
299 | (1) |
|
Protecting the Guitar Wars Admin page |
|
|
300 | (2) |
|
HTTP authentication requires headers |
|
|
302 | (2) |
|
|
304 | (1) |
|
Take control of headers with PHP |
|
|
305 | (1) |
|
Authenticating with headers |
|
|
306 | (8) |
|
Create an Authorize script |
|
|
314 | (4) |
|
Guitar Wars Episode II: Attack of the High Score Clones |
|
|
318 | (1) |
|
|
319 | (1) |
|
|
320 | (1) |
|
Plan for moderation in Guitar Wars |
|
|
321 | (1) |
|
Make room for approvals with ALTER |
|
|
322 | (5) |
|
Unapproved scores aren't worthy |
|
|
327 | (3) |
|
|
330 | (1) |
|
Everything in moderation...? |
|
|
331 | (2) |
|
How exactly did she do it? |
|
|
333 | (1) |
|
Tricking MySQL with comments |
|
|
334 | (1) |
|
The Add Score form was SQL injected |
|
|
335 | (1) |
|
Protect your data from SQL injections |
|
|
336 | (1) |
|
A safer INSERT (with parameters) |
|
|
337 | (2) |
|
Form validation can never be too smart |
|
|
339 | (2) |
|
|
341 | (4) |
|
Remember Me?: Building Personalized Web Apps |
|
|
345 | (72) |
|
They say opposites attract |
|
|
346 | (1) |
|
Mismatch is all about personal data |
|
|
347 | (1) |
|
Mismatch needs user log-ins |
|
|
348 | (3) |
|
Prepping the database for log-ins |
|
|
351 | (2) |
|
Constructing a log-in user interface |
|
|
353 | (1) |
|
Encrypt passwords with SHA() |
|
|
354 | (1) |
|
|
355 | (3) |
|
Authorizing users with HTTP |
|
|
358 | (3) |
|
Logging In Users with HTTP Authentication |
|
|
361 | (4) |
|
A form for signing up new users |
|
|
365 | (10) |
|
|
375 | (1) |
|
|
376 | (3) |
|
Rethinking the flow of log-ins |
|
|
379 | (1) |
|
|
380 | (5) |
|
Logging out means deleting cookies |
|
|
385 | (4) |
|
Sessions aren't dependent on the client |
|
|
389 | (2) |
|
Keeping up with session data |
|
|
391 | (1) |
|
Renovate Mismatch with sessions |
|
|
392 | (1) |
|
|
393 | (5) |
|
Complete the session transformation |
|
|
398 | (6) |
|
Users aren't feeling welcome |
|
|
404 | (2) |
|
Sessions are short-lived... |
|
|
406 | (1) |
|
...but cookies can last forever! |
|
|
407 | (2) |
|
Sessions + Cookies = Superior log-in persistence |
|
|
409 | (8) |
|
Sharing is Caring: Eliminate Duplicate Code |
|
|
417 | (10) |
|
|
421 | (1) |
|
Rebuilding Mismatch from a template |
|
|
422 | (2) |
|
Rebuild Mismatch with templates |
|
|
424 | (2) |
|
Mismatch is whole again...and much better organized |
|
|
426 | (1) |
|
Harvesting Data: Control Your Data, Control Your World |
|
|
427 | (74) |
|
Making the perfect mismatch |
|
|
428 | (1) |
|
Mismatching is all about the data |
|
|
429 | (2) |
|
Model a database with a schema |
|
|
431 | (5) |
|
Wire together multiple tables |
|
|
436 | (1) |
|
|
437 | (1) |
|
Tables can match row for row |
|
|
438 | (1) |
|
|
439 | (1) |
|
Matching rows many-to-many |
|
|
440 | (5) |
|
Build a Mismatch questionnaire |
|
|
445 | (1) |
|
Get responses into the database |
|
|
446 | (4) |
|
We can drive a form with data |
|
|
450 | (6) |
|
Generate the Mismatch questionnaire form |
|
|
456 | (6) |
|
Strive for a bit of normalcy |
|
|
462 | (1) |
|
When normalizing, think in atoms |
|
|
463 | (2) |
|
Three steps to a normal database |
|
|
465 | (4) |
|
Altering the Mismatch database |
|
|
469 | (1) |
|
So is Mismatch really normal? |
|
|
470 | (2) |
|
A query within a query within a query... |
|
|
472 | (1) |
|
|
473 | (1) |
|
|
474 | (1) |
|
Surely we can do more with inner joins |
|
|
475 | (2) |
|
Nicknames for tables and columns |
|
|
477 | (1) |
|
|
478 | (7) |
|
Five steps to a successful mismatch |
|
|
485 | (2) |
|
Compare users for ``mismatchiness'' |
|
|
487 | (1) |
|
All we need is a FOR loop |
|
|
488 | (13) |
|
Better Living Through Functions: String and Custom Functions |
|
|
501 | (60) |
|
A good risky job is hard to find |
|
|
502 | (2) |
|
The search leaves no margin for error |
|
|
504 | (1) |
|
SQL queries can be flexible with LIKE |
|
|
505 | (5) |
|
Explode a string into individual words |
|
|
510 | (3) |
|
implode() builds a string from substrings |
|
|
513 | (6) |
|
Preprocess the search string |
|
|
519 | (1) |
|
Replace unwanted search characters |
|
|
520 | (4) |
|
The query needs legit search terms |
|
|
524 | (1) |
|
Copy non-empty elements to a new array |
|
|
525 | (3) |
|
Sometimes you just need part of a string |
|
|
528 | (1) |
|
Extract substrings from either end |
|
|
529 | (3) |
|
Multiple queries can sort our results |
|
|
532 | (4) |
|
Functions let you reuse code |
|
|
536 | (1) |
|
Build a query with a custom function |
|
|
537 | (1) |
|
Custom functions, how custom are they really? |
|
|
538 | (4) |
|
SWITCH makes far more decisions than IF |
|
|
542 | (3) |
|
Give build_query() the ability to sort |
|
|
545 | (3) |
|
We can paginate our results |
|
|
548 | (1) |
|
Get only the rows you need with LIMIT |
|
|
549 | (1) |
|
Control page links with LIMIT |
|
|
550 | (1) |
|
Keep track of the pagination data |
|
|
551 | (1) |
|
Set up the pagination variables |
|
|
552 | (1) |
|
Revise the query for paginated results |
|
|
553 | (1) |
|
Generate the page navigation links |
|
|
554 | (3) |
|
Putting together the complete Search script |
|
|
557 | (1) |
|
The complete Search script, continued... |
|
|
558 | (3) |
|
Rules for Replacement: Regular Expressions |
|
|
561 | (44) |
|
Risky Jobs lets users submit resumes |
|
|
562 | (4) |
|
Decide what your data should look like |
|
|
566 | (3) |
|
Formulate a pattern for phone numbers |
|
|
569 | (1) |
|
Match patterns with regular expressions |
|
|
570 | (2) |
|
Build patterns using metacharacters |
|
|
572 | (7) |
|
Fine-tune patterns with character classes |
|
|
579 | (5) |
|
Check for patterns with preg_match() |
|
|
584 | (7) |
|
Standardize the phone number data |
|
|
591 | (1) |
|
Get rid of the unwanted characters |
|
|
592 | (4) |
|
Matching email addresses can be tricky |
|
|
596 | (2) |
|
Domain suffixes are everywhere |
|
|
598 | (1) |
|
Use PHP to check the domain |
|
|
599 | (1) |
|
Email validation: putting it all together |
|
|
600 | (5) |
|
Drawing Dynamic Graphics: Visualizing Your Data... and More! |
|
|
605 | (52) |
|
Guitar Wars Reloaded: Rise of the Machines |
|
|
606 | (1) |
|
|
607 | (1) |
|
We need to separate man from machine |
|
|
608 | (3) |
|
We can defeat automation with automation |
|
|
611 | (2) |
|
Generate the CAPTCHA pass-phrase text |
|
|
613 | (1) |
|
Visualizing the CAPTCHA image |
|
|
614 | (2) |
|
Inside the GD graphics functions |
|
|
616 | (4) |
|
|
620 | (3) |
|
Generate a random CAPTCHA image |
|
|
623 | (2) |
|
Returning sanity to Guitar Wars |
|
|
625 | (2) |
|
Add CAPTCHA to the Add Score script |
|
|
627 | (3) |
|
Five degrees of opposability |
|
|
630 | (1) |
|
|
631 | (1) |
|
|
632 | (3) |
|
Reading between the lines with the master of charts |
|
|
635 | (1) |
|
From one array to another |
|
|
636 | (2) |
|
Build an array of mismatched topics |
|
|
638 | (1) |
|
Formulating a bar graphing plan |
|
|
639 | (1) |
|
|
640 | (1) |
|
|
641 | (3) |
|
|
644 | (3) |
|
Draw and display the bar graph image |
|
|
647 | (3) |
|
Individual bar graph images for all |
|
|
650 | (3) |
|
Mismatch users are digging the bar graphs |
|
|
653 | (4) |
|
Interfacing to the World: Syndication and Web Services |
|
|
657 | (96) |
|
Owen needs to get the word out about Fang |
|
|
658 | (1) |
|
Push alien abduction data to the people |
|
|
659 | (1) |
|
RSS pushes web content to the people |
|
|
660 | (1) |
|
|
661 | (5) |
|
From database to newsreader |
|
|
666 | (3) |
|
|
669 | (2) |
|
What makes a newsman tick |
|
|
671 | (1) |
|
Dynamically generate an RSS feed |
|
|
672 | (4) |
|
|
676 | (2) |
|
A video is worth a million words |
|
|
678 | (2) |
|
Pulling web content from others |
|
|
680 | (1) |
|
Syndicating YouTube videos |
|
|
681 | (1) |
|
Make a YouTube video request |
|
|
682 | (4) |
|
Owen is ready to build a REST request |
|
|
686 | (4) |
|
|
690 | (4) |
|
Deconstruct a YouTube XML response |
|
|
694 | (1) |
|
Visualize the XML video data |
|
|
695 | (1) |
|
Access XML data with objects |
|
|
696 | (1) |
|
From XML elements to PHP objects |
|
|
697 | (1) |
|
Drill into XML data with objects |
|
|
698 | (1) |
|
|
699 | (2) |
|
Fang sightings are on the rise |
|
|
701 | (1) |
|
Lay out videos for viewing |
|
|
702 | (1) |
|
Format video data for display |
|
|
703 | (10) |
|
The Top Ten Topics (We Didn't Cover): Leftovers |
|
|
713 | (18) |
|
Retrofit this book for PHP4 and mysql functions |
|
|
714 | (2) |
|
User permissions in MySQL |
|
|
716 | (2) |
|
Error reporting for MySQL |
|
|
718 | (1) |
|
Exception handling PHP errors |
|
|
719 | (2) |
|
|
721 | (2) |
|
Securing your PHP application |
|
|
723 | (2) |
|
Protect your app from cross-site scripting |
|
|
725 | (2) |
|
|
727 | (1) |
|
What's the difference between PHP 5 and PHP 6 |
|
|
728 | (2) |
|
Reusing other people's PHP |
|
|
730 | (1) |
|
A Place to Play: Set Up a Development Environment |
|
|
731 | (18) |
|
Create a PHP development environment |
|
|
732 | (1) |
|
|
732 | (1) |
|
Do you have a web server? |
|
|
733 | (1) |
|
Do you have PHP? Which version? |
|
|
733 | (1) |
|
Do you have MySQL? Which version? |
|
|
734 | (1) |
|
Start with the Web Server |
|
|
735 | (2) |
|
|
737 | (1) |
|
|
738 | (1) |
|
Steps to Install MySQL on Windows |
|
|
739 | (3) |
|
|
742 | (1) |
|
Steps to Install MySQL on Mac OS X |
|
|
742 | (2) |
|
Moving from production to a live site |
|
|
744 | (1) |
|
Dump your data (and your tables) |
|
|
745 | (1) |
|
Prepare to use your dumped data |
|
|
745 | (1) |
|
Move dumped data to the live server |
|
|
746 | (1) |
|
Connect to the live server |
|
|
747 | (2) |
|
Get Even More: Extend Your PHP |
|
|
749 | (4) |
|
|
750 | (3) |
|
|
753 | |