Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 58 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
58
Dung lượng
619,8 KB
Nội dung
Selection: <select name="myselection"> <option value="nogo">make a selection </option> <option value="1"<?php if ($_POST['myselection'] == 1){?> ➥ selected="selected"<?php } ?>>Choice 1</option> <option value="2"<?php if ($_POST['myselection'] == 2){?> ➥ selected="selected"<?php } ?>>Choice 2</option> <option value="3"<?php if ($_POST['myselection'] == 3){?> ➥ selected="selected"<?php } ?>>Choice 3</option> </select><br /><br /> Your Email: <input type="text" name="youremail" maxlength="150" ➥ value="<?php echo $_POST['youremail']; ?>" /><br /> <input type="submit" value="Submit" style="margin-top: 10px;" /> </form> <?php } ?> </div> </body> </html> Figure 13-1 shows the potential output if you input a valid name field but leave the selec- tion and e-mail address empty. Figure 13-1. Telling users to properly enter information How It Works In this example, you have seen how you may want to handle your validation. Keep in mind that your objective is to ensure that users know what they did wrong and keep their properly submitted information for ease of use. To ensure that the user of this form sees the error mes- sages, the Cascading Style Sheet (CSS) class called error will be used every time an error message is displayed. The error message will display in bold and red, thus directing the users to realize what they did wrong. By providing the value fields, and in the case of the select box a selected argument if you have valid data, the form fields will retain any current, proper information. If there is no cur- rent, proper data to use, nothing will display. This form has now become decidedly easy to use, is quite secure, and ensures a happy, well-directed user. 13-5 ■ REDISPLAYING FORMS WITH PRESERVED INFORMATION AND ERROR MESSAGES498 5092_Ch13_FINAL 8/26/05 9:58 AM Page 498 Preventing Multiple Submissions of a Form One possible occurrence that happens often is that users become impatient when waiting for your script to do what it is doing, and hence they click the submit button on a form repeatedly. This can wreak havoc on your script because, while the user may not see anything happening, your script is probably going ahead with whatever it has been programmed to do. Of particular danger are credit card number submittals. If a user continually hits the sub- mit button on a credit card submittal form, their card may be charged multiple times if the developer has not taken the time to validate against such an eventuality. 13-6. Preventing Multiple Submissions on the Server Side You can deal with multiple submittal validation in essentially two ways. The first occurs on the server. Server side refers to a script located on the server that is receiving the data; client side is more browser related (and explained in the next example). Because the server has no actual access to the browser, validating multiple submissions can be a bit trickier. While you can accomplish this goal in a number of ways from a server-side perspective, we prefer to use a session-based method. Basically, once the submit button has been clicked, the server logs the request from the individual user. If the user attempts to resubmit a request, the script notes a request is already in motion from this user and denies the subsequent request. Once the script has finished processing, the session is unset, and you have no more worries. For the following example, you will need a test.txt text file that you can create and place relative to the script. (Or you can ensure that you have write privileges on the working direc- tory, and the script will attempt to create it for you.) Keep in mind that the file must have the proper privileges set for writing (CHMOD to 777 to keep things simple). The Code <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"➥ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <title>Sample 13.6</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <div style="width: 500px; text-align: left;"> <form action="sample13_6_process.php" method="post"> <p>Example:</p> <input type="hidden" name="submitted" value="yes" /> Your Name: <input type="text" name="yourname" maxlength="150” /><br /> <input type="submit" value="Submit" style="margin-top: 10px;" /> </form> </div> </body> </html> <?php //Start the session state. session_start (); 13-6 ■ PREVENTING MULTIPLE SUBMISSIONS ON THE SERVER SIDE 499 5092_Ch13_FINAL 8/26/05 9:58 AM Page 499 //Set a session started value for this user. if (!isset ($_SESSION['processing'])){ $_SESSION['processing'] = false; } //Now you ensure you haven't already started processing the request. if ($_SESSION['processing'] == false){ //Now, you let the script know that you are processing. $_SESSION['processing'] = true; //Create a loop that shows the effect of some heavy processing. for ($i = 0; $i < 2000000; $i++){ //Thinking } //Every time you do this, write to a text file so you can test that //the script isn't getting hit with multiple submissions. if ($file = fopen ("test.txt","w+")){ fwrite ($file, "Processing"); } else { echo "Error opening file."; } //Then you start doing the calculations. echo $_POST['yourname']; //Then, once you have finished calculating, you can kill the session. unset ($_SESSION['processing']); } ?> How It Works Now, enter your name and continue to jam on the submit button. Rather than allow the script to continually run time and time again, the script verifies your existence via a session and deter- mines if it is already processing your server call. If the script sees you are already processing, then it will not allow you to try again no matter how many times you click the same button. Once the script has finished performing its action, it merely unsets the session variable, and you could theoretically start again. By checking the session, the script ensures that it is the same user attempting to access the script and can therefore block multiple attempts from the same user. 13-7. Preventing Multiple Submissions on the Client Side Handling multiple submittals from a client-side perspective is actually much simpler than doing it on the server side. With well-placed JavaScript, you can ensure that the browser will not let the submittal go through more than once. The problem with this method, of course, is that JavaScript is not always foolproof because of the user’s ability to turn it off. That being said, however, most users will have JavaScript enabled, so this script will likely work for 13-7 ■ PREVENTING MULTIPLE SUBMISSIONS ON THE CLIENT SIDE500 5092_Ch13_FINAL 8/26/05 9:58 AM Page 500 90 percent of web users. The following example uses JavaScript to cut off multiple submittals from a client-side (browser) level. Don’t forget to ensure that you have a valid test.txt file (CHMOD to 777), as specified in the previous recipe. The Code <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"➥ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <title>Sample 13.7</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <script language="javascript" type="text/javascript"> <! function checkandsubmit() { //Disable the submit button. document.test.submitbut.disabled = true; //Then submit the form. document.test.submit(); } // > </script> </head> <body> <div style="width: 500px; text-align: left;"> <form action="sample13_6_process.php" method="post" name="test" ➥ onsubmit="return checkandsubmit ()"> <p>Example:</p> <input type="hidden" name="submitted" value="yes" /> Your Name: <input type="text" name="yourname" maxlength="150" /><br /> <input type="submit" value="Submit" style="margin-top: 10px;" ➥ id="submitbut" name"submitbut" /> </form> </div> </body> </html> <?php //Create a loop that shows the effect of some heavy processing. for ($i = 0; $i < 2000000; $i++){ //Thinking } //Every time you do this, let's write to a text file so you can test that //out script isn't getting hit with multiple submissions. if ($file = fopen ("test.txt","w+")){ fwrite ($file, "Processing"); } else { 13-7 ■ PREVENTING MULTIPLE SUBMISSIONS ON THE CLIENT SIDE 501 5092_Ch13_FINAL 8/26/05 9:58 AM Page 501 echo "Error opening file."; } //Then you start doing the calculations. echo $_POST['yourname']; ?> How It Works We realize that this particular piece of functionality is based on JavaScript and this is a book about PHP, but PHP is a server-side language. Therefore, to do a little client-side validation, you must use a language that can interact with the browser, such as JavaScript. In any case, the way this script works is by actually disabling the submit button once the form has been submitted. The button is clicked, which forces the browser to redirect first to the JavaScript function checkandsubmit(), which immediately disables the submit button and then submits the form for you. At this point, it does not matter how long the script takes to finish executing; the submit button is disabled and hence cannot be clicked again until the page is revisited. 13-8. Performing File Uploads Handling file uploads in PHP is not exactly difficult from a syntax point of view, but it is important (extremely important in fact) to ensure that the file being uploaded is within the upload constraints you lay out for it. In other words, an individual user could easily upload a virus or some other form of malicious software if you are not careful about allowing them to upload only what you want from them. A similar consideration is file size. You could easily find your server under some heavy loads if you are not careful about what size of files are being uploaded. The following example allows you to upload an image (of the file type JPG only) that is smaller than 500KB in size. Keep in mind that in order for this script to work, you must have a directory created (rela- tive to the script) that is called uploads and is writable (again, using a CHMOD of 777 is the simplest way of accomplishing this). The Code <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"➥ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <title>Sample 13.8</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <div style="width: 500px; text-align: left;"> <?php //If you have received a submission. if ($_POST['submitted'] == "yes"){ $goodtogo = true; //Check for a blank submission. 13-8 ■ PERFORMING FILE UPLOADS502 5092_Ch13_FINAL 8/26/05 9:58 AM Page 502 try { if ($_FILES['image']['size'] == 0){ $goodtogo = false; throw new exception ("Sorry, you must upload an image."); } } catch (exception $e) { echo $e->getmessage(); } //Check for the file size. try { if ($_FILES['image']['size'] > 500000){ $goodtogo = false; //Echo an error message. throw new exception ("Sorry, the file is too big at approx: " ➥ . intval ($_FILES['image']['size'] / 1000) . "KB"); } } catch (exception $e) { echo $e->getmessage(); } //Ensure that you have a valid mime type. $allowedmimes = array ("image/jpeg","image/pjpeg"); try { if (!in_array ($_FILES['image']['type'],$allowedmimes)){ $goodtogo = false; throw new exception ("Sorry, the file must be of type .jpg. ➥ Yours is: " . $_FILES['image']['type'] . ""); } } catch (exception $e) { echo $e->getmessage (); } //If you have a valid submission, move it, then show it. if ($goodtogo){ try { if (!move_uploaded_file ($_FILES['image']['tmp_name'],"uploads/". ➥ $_FILES['image']['name'].".jpg")){ $goodtogo = false; throw new exception ("There was an error moving the file."); } } catch (exception $e) { echo $e->getmessage (); } } if ($goodtogo){ //Display the new image. ?><img ➥ alt="" title="" /><?php } 13-8 ■ PERFORMING FILE UPLOADS 503 5092_Ch13_FINAL 8/26/05 9:58 AM Page 503 ?><br /><a href="sample13_8.php">Try Again</a><?php } //Only show the form if there is no submission. if ($_POST['submitted'] != "yes"){ ?> <form action="sample13_8.php" method="post" enctype="multipart/form-data"> <p>Example:</p> <input type="hidden" name="submitted" value="yes" /> Image Upload (.jpg only, 500KB Max):<br /> ➥ <input type="file" name="image" /><br /> <input type="submit" value="Submit" style="margin-top: 10px /> </form> <?php } ?> </div> </body> </html> A sample execution of this script could lead to a certain someone appearing on your monitor (see Figure 13-2). Figure 13-2. Beware of Darth Vader. How It Works The first aspect of this script you need to know about is that PHP 5 handles file uploads through the superglobal $_FILES. By accessing certain elements of this superglobal, you can find out certain information about the file upload. Table 13-2 lists data you can retrieve from the $_FILES superglobal. The next important aspect to uploading files takes place in the form element itself. If you plan to pass along a file, you must include the code enctype="multipart/ form-data", or else the script will appear to function successfully without ever actually passing along a file. 13-8 ■ PERFORMING FILE UPLOADS504 5092_Ch13_FINAL 8/26/05 9:58 AM Page 504 Table 13-2. $_FILES Arguments Argument Description name The original filename that was uploaded type The MIME type of the uploaded file size The size of the uploaded file (in bytes) tmp_name The temporary name of the file that has been uploaded error The error code that may be generated by the file upload From this point on, the rest is merely a matter of validation. By comparing the file type against an array of allowed MIME types, you can completely shut out malicious file uploads (because the MIME type will return the absolute type of the file). Size validation is handled in bytes, so if you plan on limiting it according to megabytes or kilobytes, you must do a few calculations (such as bytes multiplied by 1,000 in this case to return a kilobyte result). As for moving the actual file and saving it, you can use two methods for performing this action. The two functions in PHP that will allow you to save a file are the copy() and move_uploaded_file() functions. We prefer to use the move_uploaded_file() function, as it will work even when PHP’s safe mode is enabled. If PHP has its safe mode enabled, the copy() function will fail. They both work largely the same, so there is no real downside to using the move_uploaded_file() function over the copy() function. 13-9. Handling Special Characters An added security feature, particularly when dealing with database submittal, is validating against special characters being inserted into your script. Be it a database insertion script, a contact form, or even a mailer system, you always want to ensure that no malicious users are attempting to sabotage your script with bad (or special) characters. PHP allots a number of functions to use in this regard. In the following example, you will look at the functions trim(), htmlspecialchars(), strip_tags(), and addslashes(). Their prototypes are as follows: string trim ( string str [, string charlist] ) string htmlspecialchars ( string string [, int quote_style [, string charset]] ) string strip_tags ( string str [, string allowable_tags] ) string addslashes ( string str ) The Code <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"➥ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <title>Sample 13.9</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <div style="width: 500px; text-align: left;"> <?php //If you have received a submission. 13-9 ■ HANDLING SPECIAL CHARACTERS 505 5092_Ch13_FINAL 8/26/05 9:58 AM Page 505 if ($_POST['submitted'] == "yes"){ $yourname = $_POST['yourname']; //You can trim off blank spaces with trim. $yourname = trim ($yourname); //You can cut off code insertion with strip_tags. $yourname = strip_tags ($yourname); //You can turn any special characters into safe ➥ representations with htmlspecialchars. $yourname = htmlspecialchars ($yourname); //And you can prepare data for db insertion with addslashes. $yourname = addslashes ($yourname); //And echo the result. echo $yourname . "<br />"; ?><a href="sample13_9.php">Try Again</a><?php } //Show the form only if there is no submission. if ($_POST['submitted'] != "yes"){ ?> <form action="sample13_9.php" method="post"> <p>Example:</p> <input type="hidden" name="submitted" value="yes" /> Your Name: <input type="text" name="yourname" maxlength="150" /><br /> <input type="submit" value="Submit" style="margin-top: 10px;" /> </form> <?php } ?> </div> </body> </html> How It Works The four functions you have put into play perform different actions on a submitted variable. The trim() function removes any blank space found at the beginning or end of the submitted string. The htmlspecialchars() function turns attempted HTML into its special character equivalent. For instance, if you enter an ampersand (&) symbol, the system will change that symbol into a harmless &. The strip_tags() function completely removes any characters it sees as being a tag. You can delimit to the function which tags you want stripped as well. The last function, addslashes(), places a slash in front of any characters that could be harmful to the database such as apostrophes. The end result is a string that is quite squeaky clean, and you can feel safe performing functionality on it. 13-10. Creating Form Elements with Multiple Options From time to time, it will occur to you as a developer that you may need to retrieve several val- ues from the same select box. Luckily, HTML and PHP 5 have made an allowance for such a 13-10 ■ CREATING FORM ELEMENTS WITH MULTIPLE OPTIONS506 5092_Ch13_FINAL 8/26/05 9:58 AM Page 506 feature. Commonly referred to as a list box, the functionality involved allows you to select a multitude of items (by holding down the Control key) and then submit them as one. The fol- lowing example allows you to select a number of items and then display only the selected items in the script. The Code <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"➥ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <title>Sample 13.10</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <div style="width: 500px; text-align: left;"> <?php //If you have received a submission. if ($_POST['submitted'] == "yes"){ //Check if any have been selected. if (count ($_POST['fruit']) != 0){ echo "Your Selections:<br />"; } else { echo "You have not made any selections.<br /><br />"; } //You can actually treat the submittal as an array. for ($i = 0; $i < count ($_POST['fruit']); $i++){ echo $_POST['fruit'][$i] . "<br />"; } ?><a href="sample13_10.php">Try Again</a><?php } //Show the form only if there is no submission. if ($_POST['submitted'] != "yes"){ ?> <form action="sample13_10.php" method="post"> <p>Example:</p> <input type="hidden" name="submitted" value="yes" /> Your Choice (s): <br /> <select name="fruit[]" multiple="multiple" style="width: 400px; ➥ height: 100px;"> <option value="Bananas">Bananas</option> <option value="Apples">Apples</option> <option value="Oranges">Oranges</option> <option value="Pears">Pears</option> <option value="Grapes">Grapes</option> <option value="Kiwi">Kiwi</option> </select><br /> <input type="submit" value="Submit" style="margin-top: 10px;" /> </form> 13-10 ■ CREATING FORM ELEMENTS WITH MULTIPLE OPTIONS 507 5092_Ch13_FINAL 8/26/05 9:58 AM Page 507 [...]... markup and Extensible Markup Language (XML) The industry is leaning more and more toward XML as a portable and extremely valuable form of both data collection and data porting, and Chapter 14 will showcase some of PHP 5 s robust handling of XML 51 1 50 92 _Ch13_FINAL 8/26/ 05 9 :58 AM Page 51 2 50 92 _Ch14_FINAL 8/26/ 05 9 : 59 AM CHAPTER Page 51 3 14 ■■■ Working with Markup P HP was originally designed as a way... 50 92 _Ch14_FINAL 8/26/ 05 9 : 59 AM Page 53 3 14-7 ■ USING RSS FEEDS RSS feeds are available from a broad range of servers and organizations, and you can use the simple script in the previous example to create a script that will replicate the content of multiple RSS feeds into a local database Many of these feeds require local caching to avoid overloading the service; as shown in the next example, you can... value of an attribute The methods are called hasAttribute(), removeAttribute(), and getAttribute() These functions all take the attribute name as the only parameter 50 92 _Ch14_FINAL 8/26/ 05 9 : 59 AM Page 52 3 14 -5 ■ PARSING XML 14 -5 Parsing XML So far we have been discussing generating HTML and XML documents, but you can also use the DOM extension to load and parse both HTML and XML documents Unlike XML documents,... it comes to manually generating content You can generate almost any content type, but this opens the possibility for generating 50 92 _Ch14_FINAL 8/26/ 05 9 : 59 AM Page 51 5 14-2 ■ MANUALLY GENERATING MARKUP documents with errors A missing closing tag will cause an error in an XML document but might not do that in HTML The next example shows how a result set from a database query can generate a simple XML... document anyway With XML, it is required that tags come in pairs, so must have a corresponding tag for the document to be 51 5 50 92 _Ch14_FINAL 51 6 8/26/ 05 9 : 59 AM Page 51 6 14-3 ■ USING DOM TO GENERATE MARKUP valid The only exception to this is for a tag that is empty and does not contain any children You can write such a tag as The slash before the end of the tag... applied to the element where the attribute is defined, and it takes two string parameters The first parameter is the name of the attribute, and the second parameter is the 50 92 _Ch14_FINAL 8/26/ 05 9 : 59 AM Page 52 1 14-4 ■ CREATING AND SETTING ATTRIBUTES value If the attribute name does not exist on the element where setAttribute is called, the attribute will be created ■ Note The parameter name is case-sensitive,... http://www .php. net/downloads .php# v5.1 [description] => PHP 5. 1 Beta 2 is now available! A lot of work has been put into this upcoming release and we believe it is ready for public testing Some of the key improvements of PHP 5. 1 include: PDO (PHP Data Objects) - A new native database abstraction layer providing performance, ease-of-use, and flexibility Significantly improved language performance mainly due... designate the field as something that can be read as an array by adding the [] to the end of the element name Once PHP gets a hold of the posted value, it treats the value as an array By walking through the array one element at a time using a for loop, you can output the selections by merely outputting the value of the array If a particular option was not selected, it simply will not show up in the array... Attributes So far you have seen documents where all the elements are as simple as a tag name In many cases, documents require that the elements or tags have attributes that specify additional information for each tag An example is the table element in the HTML documents you have created The table element can include attributes such as width, height, and border as well as several others The createElement()... xmlns:backslash="http://slashdot.org/backslash.dtd"> Dell Axim X50 Running Linux http://slashdot.org/article.pl?sid= 05/ 06/ 15/ 022211 20 05- 06- 15 04:10:00 52 3 50 92 _Ch14_FINAL 52 4 8/26/ 05 9 : 59 AM Page 52 4 14 -5 ■ PARSING XML timothy tempty-tempty 100 0 hardware topichandhelds.gif . robust handling of XML. 13-11 ■ CREATING FORM ELEMENTS BASED ON THE CURRENT TIME AND/OR DATE 51 1 50 92 _Ch13_FINAL 8/26/ 05 9 :58 AM Page 51 1 50 92 _Ch13_FINAL 8/26/ 05 9 :58 AM Page 51 2 Working with Markup PHP. you have received a submission. 13 -9 ■ HANDLING SPECIAL CHARACTERS 50 5 50 92 _Ch13_FINAL 8/26/ 05 9 :58 AM Page 50 5 if ($_POST['submitted'] == "yes"){ $yourname = $_POST['yourname']; //You. function. 13 -9. Handling Special Characters An added security feature, particularly when dealing with database submittal, is validating against special characters being inserted into your script. Be it a