Create a new file called addimages.php and add the following form: ”>see your item!. $SCRIPT_NAME If this battery of tests does not cause the page to reload with an error, the image is l
Trang 1$db = mysql_connect($dbhost, $dbuser, $dbpassword);
spe-Next, you check the result of the function and act accordingly First, check tosee if the date is valid:
Trang 2248 Practical PHP and MySQL
as the hour, and 30 as the minute With these numbers, the valid date would be2005-12-10 11:30 The sprintf()function (which you used earlier to pad priceswith zeros) was used again, this time to ensure that single digits have a leading zero(so 1 would become 01 and so on) This is important for the date to be a validMySQL date
Construct the query to insert the data:
$concatdate = $_POST[‘year’]
“-” sprintf(“%02d”, $_POST[‘day’]) “-” sprintf(“%02d”, $_POST[‘month’]) “ “ $_POST[‘hour’]
“:” $_POST[‘minute’]
“:00”;
$itemsql = “INSERT INTO items(user_id, cat_id, name,
startingprice, description, dateends) VALUES(“
$_SESSION[‘USERID’]
“, “ $_POST[‘cat’]
“, ‘“ addslashes($_POST[‘name’]) “‘, “ $_POST[‘price’]
“, ‘“ addslashes($_POST[‘description’]) “‘, ‘“ $concatdate
Finally, a header redirect jumps to the addimages.php page and passes it a GET
variable, called id, with the insert id
Earlier in the code, you made a check to see if the date was valid If the datewas invalid, reload the page and pass the error flag:
header(“Location: “ $config_basedir “/addimages.php?id=”
Trang 3The Risks with Input
When you accept any kind of input from a user, there is a risk that the inputcould break the query The most common breakage occurs when a usertypes a single quotation mark, because the quotation mark ends the inputand anything after the second quotation mark is ignored Imagine that theuser types ‘Tim O’Chin’ The query would be as follows:
INSERT INTO users(name) VALUES(‘Tim O’Chin’);
In this query, the second quotation mark (in O’Chin) ends the input andcauses a SQL error
In your projects, it is unlikely that you have encountered this error This isbecause a feature called magic_quotes is likely to be turned on in your
php.ini file With this feature, any quotation marks accepted from a form
are automatically escaped The act of escaping a quotation mark happenswhen you use a forward slash to make the quotation mark legitimate Assuch, a properly escaped query would be:
INSERT INTO users(name) VALUES(‘Tim O\’Chin’);
You can run this project with magic_quotes turned off if you wrap yourdata withaddslashes(); this function escapes the quotation marks
After closing the main ifblock, begin the elsethat displays the form:
<h1>Add a new item</h1>
<strong>Step 1</strong> - Add your item details.
After the form, add the closing curly bracket and footer code:
Trang 4250 Practical PHP and MySQL
Adding the Images
Being able to upload images is a common and useful skill used when developingWeb sites The basic technique is as follows:
1. Provide a form the user can use to select an image
2. When the user clicks the Submit button, transfer the image to a temporarylocation on the server Inside this location, give the file a random, temporaryfilename
3. Check that the image is valid and copy it to a specific directory on the Webserver
4. Add the name of the image and the id of the item it is associated with to the
images table.
With this process complete, you can iterate through the images table for items
with the same idand then add the filename to the image HTML tag from the table
Create a new file called addimages.php and add the following form:
<form enctype=”multipart/form-data” action=”<?php
When you have finished adding photos, go and
<a href=”<?php echo “itemdetails.php?id=”
$validid; ?>”>see your item</a>!
Within the form tag, you created a new attribute, called enctype, that ensuresthe form submits the image data in an understandable format The first <input>tagcreates a special hiddenform element that can be used to store hidden informationand variables in the form In this example, the hiddenelement stores the maximumsize of the image The second input element is a userfile type and adds a browsebutton that the user can click to select the image to upload The preceding codealso adds a Submit button
Trang 5Jump to the beginning of the page (before the form) and start adding the code toprocess the form:
$validid = pf_validate_number($_GET[‘id’], “redirect”, “index.php”);
After the usual introductory code, protect the page from users who are notlogged in:
$validid = pf_validate_number($_GET[‘id’], “redirect”, “index.php”);
if(isset($_SESSION[‘USERNAME’]) == FALSE) {
header(“Location: “ $HOST_NAME
“login.php?ref=images&id=” $validid);
}
Select theuser_idfrom the items table for the current item This is required so
you can check that the owner of the item—not a random user—is accessing the page.if(isset($_SESSION[‘USERNAME’]) == FALSE) {
Trang 6252 Practical PHP and MySQL
This code checks to see if the nameinformation in the $_FILESarray has a value
If it does not, the page reloads with an appended error variable
Now you can run a further set of tests First, check to see if the size is legitimate(not zero):
header(“Location: “ $HOST_NAME $SCRIPT_NAME
Trang 7Check that the size is not greater than the maximum file size set in the hiddenfield:
header(“Location: “ $HOST_NAME $SCRIPT_NAME
header(“Location: “ $HOST_NAME $SCRIPT_NAME
If this battery of tests does not cause the page to reload with an error, the image
is legitimate and the file can be copied to a safe directory
First, specify the safe directory for images:
header(“Location: “ $HOST_NAME $SCRIPT_NAME
Temporary Means Temporary
When you upload the image with the form, the file is stored in a temporarydirectory This directory really is temporary and is likely to be cleaned outregularly or on reboot
Configure this directory inside php.ini by setting the upload_tmp_dir option
in php.ini.
Trang 8254 Practical PHP and MySQL
You create a variable called $uploaddir, which should point to a legitimate
location inside the main project directory Create a new directory called images
with read and write access permissions and change $uploaddir to your directory.The second line concatenates this directory and adds the file name The $upload- dirvariable needs a trailing forward slash (/) to ensure that the image name is con-catenated correctly
Copy the file and add the name to the database:
into the images table and reload the page.
If for some reason move_uploaded_file() fails (such as incorrect file sions), display an error message:
permis-header(“Location: “ $HOST_NAME $SCRIPT_NAME “?id=” $validid);
Trang 9echo “<td>[<a href=’deleteimage.php?image_id=”
$imagesrow[‘id’] “&item_id=” $validid
image, a link is made to a page called delete.php, and the id of both the image and
item are added to the link as GETvariables
After the images are displayed, the form is displayed Just before the form code,add a switchstatement to display the errors:
Trang 10256 Practical PHP and MySQL
<a href=”<?php echo “itemdetails.php?id=”
$validid; ?>”>see your item</a>!
In this section, you create the Delete page that was created in the previous script
When the user clicks the Delete link, the delete.php page prompts you to verify
that you want to delete the image With this message, there will be two Submit tons, with either Yes and No written on them You can then check which Submitbutton has been clicked and respond accordingly:
but-■ If the user clicks the Yes button, the image is deleted, the record is removed
from the images table, and the page redirects to addimages.php.
■ If the user clicks the No button, the page redirects to addimages.php.
The first step is to add the form Create a new page called deleteimage.php andthe following code:
<h2>Delete image?</h2>
<form action=”<?php echo
pf_script_with_get($SCRIPT_NAME); ?>” method=”post”>
Trang 11FIGURE 7-6 An item can have a number of images attached to it.
Are you sure you want to delete this image?
<p>
<input type=”submit” name=”submityes”
value=”Yes”> <input type=”submit” name=”submitno” value=”No”>
Trang 12258 Practical PHP and MySQL
Check to see if the Yes button was clicked (submityes):
If the Yes button is clicked, the query selects the name of the image from the
images table with the id of $validimageid After the query is run, the unlink()command physically deletes the file Finally, the DELETEquery removes the record,and the page is redirected
If the No button is clicked, the page redirects to addimages.php:
header(“Location: “ $config_basedir “addimages.php?id=”
echo pf_script_with_get($SCRIPT_NAME); ?>” method=”post”>
Finally, at the bottom of the file, add the closing code:
Trang 13The solution is to first create a page that determines which auctions have endedand sent the emails To ensure processing is kept to a minimum, the endnotified
field in the items table is set to 1when an item has been processed As such, youcan search for items with an enddate older than NOW() in which endnotifed is0.This page can be used to process all auctions by simply running it
To solve the problem of processing the auctions when they have finished, youcan use a scheduled tasks tool such as cron(Linux) or Windows Scheduler (Win-dows) to schedule that the page is accessed approximately every five minutes Youcan use the wgetcommand-line tool to do this
Create a page called processauctions.php and run a query to select all the items:
<?php
require(“config.php”);
require(“header.php”);
$itemssql = “SELECT users.username, users.email, items.id,
items.name FROM items, users WHERE dateends < NOW() AND
items.user_id = users.id AND endnotified = 0;”;
$itemsresult = mysql_query($itemssql);
This query selects the username, email, item id, and name for all records inwhich dateends is in the past and in which endnotified is set to 0 Each recordreturned is an ended auction
Trang 14260 Practical PHP and MySQL
Iterate through the records:
$itemssql = “SELECT users.username, users.email, items.id,
items.name FROM items, users WHERE dateends < NOW() AND
items.user_id = users.id AND endnotified = 0;”;
$itemsresult = mysql_query($itemssql);
while($itemsrow = mysql_fetch_assoc($itemsresult)) {
$bidssql = “SELECT bids.amount, users.username,
users.email FROM bids, users WHERE bids.user_id = users.id
AND item_id = “ $itemsrow[‘id’] “ ORDER BY amount
With the data gathered, now you can construct and send the emails To generate
the mails, use the heredoc syntax that was discussed in Chapter 5 When using this
syntax, you cannot use arrays inside it Instead, extract data into normal variables:
■ The owner of the auction to indicate that no bids were made on the item
■ The owner to indicate the highest bidder and the bidder’s contact details
■ The winning bidder to indicate the owner of the auction
First, create the one that is sent to the owner indicating that no bids were made
To see if there were any bids, check if the $bidsnumrowshas a value If not, createthe following email message:
$own_email = $itemsrow[‘email’];
$own_name = $itemsrow[‘name’];
Trang 15mail($own_email, “Your item ‘“ $own_name
“‘ did not sell”, $owner_body);
}
If there were rows in the bids table, construct the other two types of email
message:
mail($own_email, “Your item ‘“ $own_name
“‘ did not sell”, $owner_body);
Congratulations! The auction for your item ‘$own_name’,
has completed with a winning bid
of $config_currency$own_highestbid bidded by $win_winner!
Bid details:
Item: $own_name
Amount: $config_currency$own_highestbid
Winning bidder: $win_winner ($win_email)
It is recommended that you contact the winning bidder within 3 days.
_OWNER_;
$winner_body=<<<_WINNER_
Hi $win_winner,
Congratulations! Your bid of $config_currency$own_highestbid for
the item ‘$own_name’ was the highest bid!
Trang 16262 Practical PHP and MySQL
Bid details:
Item: $own_name
Amount: $config_currency$own_highestbid
Owner: $own_owner ($own_email)
It is recommended that you contact the owner of the item within 3 days _WINNER_;
mail($own_email, “Your item ‘“ $own_name
“‘ has sold”, $owner_body);
mail($win_email, “You won item ‘“ $own_name
“‘!”, $winner_body);
Update the items table and set endnotifiedto1to indicate that the auction hasbeen processed:
mail($own_email, “Your item ‘“ $own_name
“‘ has sold”, $owner_body);
mail($win_email, “You won item ‘“ $own_name
S CHEDULING THE P AGE TO B E R UN
To schedule the page to be run at regular intervals, use the wget download utility toperform the visit The wget utility is mainly used for downloading files, so on Linuxyou will need to send any output to /dev/null:
foo@bar:~$ wget –-delete-after
http://localhost/auction/processauctions.php
Trang 17To schedule this to occur at regular intervals, add the following line to a cronjob First, load the crontabwith the following:
foo@bar:~$ crontab –e
To run the command every five minutes, add the following line to the crontab:
Many more possibilities exist for adding more functionality, and as you learnmore and more features in PHP, you can return to this project to enhance differentparts of the code An example of this is the form handling In this project, you delib-erately processed the forms manually to learn how to use addslashes()to handleuser input In a later project, you will use HTML_QuickForm to manage the forms
TIP
Another possibility is to add an administration section with tools to age the auction site in the same way we have developed administration sec-tions in previous projects Each project in this book is not intended to be acomplete, finished application, and there is plenty of scope to add addi-tional features and improve the projects in different ways Simply use yourimagination and fill in the gaps where needed This is part of the fun ofsoftware development—when you know the technology, the sky is the limit.Good luck!
Trang 18man-This page intentionally left blank
Trang 19In this project, you will create a Web-based calendar to help with these gles The project implements everything you need to manage your life—the ability
strug-to view months at a time, display event information, and add new events Althoughsimple in concept, calendars offer a number of interesting challenges for develop-ers To make the project even more interesting, you explore Ajax, a technology setthat provides for highly dynamic Web sites that function much like desktop appli-cations Plug yourself in, stretch those fingers, and get ready!
P ROJECT O VERVIEW
To get a clear idea of how the project will work, take a look at the following use case:Susan has a terrible memory Although she is extremely popular among herfriends and co-workers, Susan often accepts invitations to parties and eventsand then promptly forgets about them After one too many missed dinnerappointments, she decides to use a Web-based calendar, one she can accessfrom any Web browser, anywhere in the world
Susan goes to her calendar and enters her login details After she fully logs in, she can see the current month, as well as each of the events shebooked for that month—all located on the correct day The calendar’s sidebar
Trang 20success-266 Practical PHP and MySQL
events
id date starttime endtime name description
users
id username password
infor-Susan realizes that she added an event for the coming Saturday, which sheneeds to cancel To delete it, she clicks the X button next to event The cal-endar is updated, and the event disappears
Susan now needs to add a new event (her dachshund’s training class) to thecalendar She clicks on the day that the class is scheduled, and the sidebar isredrawn with a form that she can fill in She adds the name of the event, thestart and end times, and a short description She then clicks the Add Eventbutton, and the calendar refreshes, displaying the new event
B UILDING THE D ATABASE
The database you will create is shown in Figure 8-1
With only two tables in the project (neither of which are related), this is anincredibly simple database to set up The events table contains a list of the events
in the calendar, and the users table contains the user logins
Implementing the Database
Start phpMyAdmin Create a new database called simplecal and add the followingtables
The events Table
■ id Make this an INT(several events are possible) and turn on ment Set this field as a primary key
auto_incre-■ date Make this a DATE
■ starttime Make this a TIME
■ endtime Make this a TIME
■ name Make this a VARCHARwith a length of 50
■ description Make this a TEXT
Trang 21TABLE 8-1 Sample events make it easier to check if the calendar works.
D ATE STARTTIME ENDTIME NAME DESCRIPTION
2007-10-14 12:00:00 14:00:00 Meeting with
Emily
Important ing to discuss future projects 2007-10-14 18:00:00 19:30:00 Meal with Lee Meal with Lee
meet-to celebrate working together.
2007-11-20 08:30:00 09:30:00 Working
breakfast
Meeting with Cliff to talk shop.
The logins Table
■ id Make this a TINYINTand turn on auto_increment Set this field as a
primary key
■ username Make this a VARCHARwith a length of 10
■ password Make this a VARCHARwith a length of 10
Insert Sample Data
In this section, you add some sample data to get started Remember, do not fill in anumber in the id column; auto_increment takes care of this for you Feel free toadd your own sample data or use the data shown in Table 8-1
Sample Data for the events Table
Add the sample events from Table 8-1
Sample Data for the logins Table
Add a username and password for the logins table (and keep the password handy!).
S TARTING TO C ODE
First, you need to take care of the site template, style, and some utility functions.Then you can move into login screens and the actual calendar pages and scripts
Trang 22268 Practical PHP and MySQL
Site Layout and Style
As you’ve done in previous chapters, the first step is to create the configuration,
header, and footer files Create a new directory called simplecal Now copy the db.php file from previous projects to the simplecal directory Next, create a new file called config.php, the contents of which are shown in Example 8-1.
EXAMPLE 8-1 A simple configuration file
Just as config.php was used in previous projects, the same stylesheet from
previous projects is used here You will need to make a few additions at the
bottom, however Create a new file called stylesheet.css and add the code shown in
Example 8-2
EXAMPLE 8-2 The additional elements in the stylesheet are used to
customize the calendar view
Trang 23font: bold 140% trebuchet ms, sans-serif;
margin: 0 auto 0 auto;
border-bottom: 1px solid #eee;
Trang 24270 Practical PHP and MySQL
Trang 26272 Practical PHP and MySQL