Section 12.4. Presenting a Form to Add and Process in One File


12.4. Presenting a Form to Add and Process in One File

We're building a form that allows a web user to add a title to the books table. Example 12-6 is a slightly longer example, because we display and process the form in one file, but it should look familiar to you since we're simply combining several steps that we've done separately before.

Example 12-6. Using input from a form to add a title

 <?php // Define a function to perform the database insert and display the titles function insert_db($title, $pages){ require_once('db_login.php'); require_once('DB.php'); $connection = DB::connect("mysql://$db_username:$db_password@$db_host/$db_database"); if (DB::isError($connection)){ die ("Could not connect to the database: <br />". DB::errorMessage($connection)); } // The query includes the form sumbission values that were passed to the function $query = "INSERT INTO `books` VALUES (NULL,'$title','$pages')"; $result = $connection->query($query); if (DB::isError($result)){ die("Could not query the database: <br />". $query." ".DB::errorMessage($result)); } echo "Inserted OK.<br />"; // Display the table $query = "SELECT * FROM `books`"; $result = $connection->query($query); if (DB::isError($result)){ die("Could not query the database: <br />". $query." ".DB::errorMessage($result)); } echo '<table border="1">'; echo "<tr><th>Title</th><th>Pages</th></tr>"; while ($result_row = $result->fetchRow(DB_FETCHMODE_ASSOC)) { echo "<tr><td>"; echo $result_row["title"] . '</td><td>'; echo $result_row["pages"] . '</td></tr>'; } echo "</table>"; $connection->disconnect(); } ?> <html> <head> <title>Inserting From a Form</title> </head> <body> <?php // Retrieve the variable from the form submission $title = $_GET["title"]; $pages = $_GET["pages"]; if (($title != NULL ) && ($pages != NULL)){ insert_db($title,$pages); } else { // Display the form echo ' <h1>Enter a new title:</h1> <form action="'.$_SERVER["PHP_SELF"].'" method="GET"> <label> Title: <input type="text" name="title"  /> </label> <label> Pages: <input type="text" name="pages"  /> </label> <input type="submit" value="Go!" /> </form>'; } ?> </body> </html> 

Example 12-6 begins by displaying a form like Figure 12-6, using the code in the body of the file if the $title and $pages values do not have both values set.

Figure 12-6. This is how the form looks with some sample data in the field


Once the user enters values into both fields and clicks the Go! button, the same script handles the form submission processing. Since values exist for the two fields, the insert_db function is called with those values. The values are placed into the query string enclosed by single quotes (' '):

 $query = "INSERT INTO 'books' VALUES (NULL,'$title','$pages')"; 

This query is then executed like any other query. Finally, the function queries the books table and displays the resuss in an HTML table.

Figure 12-7 shows what happens after clicking the Go! button with the sample data above.

Figure 12-7. The results page shows the new entry


You must take several precautions when working with strings submitted from a form that will be processed by the database.

12.4.1. SQL Injection

Specifically, you need to be on guard for a tactic called SQL injection. SQL injection is when a malicious user enters another SQL query into a field such as 1,1);drop table users;. When this query is added to a query like this:

 $query = "INSERT INTO 'books' VALUES (NULL,$title,$pages)"; 

here's what could happen:

 $query = "INSERT INTO 'books' VALUES (NULL,1,1);drop table users; ,$pages)"; 

PHP and MySQL work together to thwart this kind of attack. What happens is the MySQL query command allows only one statement per query. So attempting to start a new query after the first one has already been started generates an error. Additionally, PHP uses a system by default called magic quotes with user input. Magic quotes automatically escape any special characters with a backslash (\), including single and double quotes.

Example 12-7 shows how to test whether magic quotes are enabled on your installation of PHP.

Example 12-7. Checking for magic quotes

 <?php if (get_magic_quotes_gpc()) { echo "Magic quotes are enabled."; } else { echo "Magic quotes are disabled."; } ?> 

The script should return:

 Magic quotes are enabled. 

Because the PEAR DB abstraction layer is being used, MySQL-specific escaping should not be used simultaneously. Use the PEAR escapeSimple($string) function to do your escaping with PEAR code.

If magic quotes are off, you can use the add_slashes function to accomplish the same thing with your input. Nonetheless, you should look out for these errors, since other databases may allow more than one statement per query. Be skeptical of user input, or you could end up with a compromised database.

12.4.2. Cross-Site Scripting Attacks

One last gotcha to look out for when using data from user input is the risk of cross-site scripting attacks. These attacks work slightly differently than SQL injection. They don't compromise the data on your server, but instead can lead to a user's browser giving out sensitive data to a third party because the browser thinks the command came from your trusted site. To guard against these attacks, you should pass any strings that came from a user through the htmlentities function. It takes the format:

 htmlentities(string_to_clean) 

For example:

 print "The title of the book is: " . htmlentities($_POST['title']); 

Here's an example of what htmlentities does to the string:

 <?php $sample = "A sample is <i>italics</i>"; echo htmlentities($sample); ?> 

When executed, this returns:

 A sample is &lt;i&gt;italics&lt;/i&gt; 

Essentially, you're guarding against the same problem as SQL injection, but the code that's vulnerable is the HTML. The special function HTML characters such as less than (<) and greater than (>) are escaped, preventing hostile HTML code from working when displayed from your site.

Here's a script to display the title table with the htmlentities functionality added:

 <?php require_once('db_login.php'); require_once('DB.php'); $connection = DB::connect("mysql://$db_username:$db_password@$db_host/$db_database"); if (DB::isError($connection)){ die ("Could not connect to the database: <br />". DB::errorMessage($connection)); } // Dislplay the table $query = "SELECT * FROM `books`"; $result = $connection->query($query); if (DB::isError($result)){ die("Could not query the database: <br />".$query." ".DB::errorMessage($result)); } echo '<table border="1">'; echo "<tr><th>Title</th><th>Pages</th></tr>"; while ($result_row = $result->fetchRow(DB_FETCHMODE_ASSOC)) { echo "<tr><td>"; echo htmlentities($result_row["title"]) . '</td><td>'; echo htmlentities($result_row["pages"]) . '</td></tr>'; } echo "</table>"; $connection->disconnect(); ?> 

Figure 12-8 shows that htmlentities didn't change the look of your table.

Figure 12-8. No change is made to the look of your table


You can be assured that you've prevented any malicious HTML that may have been entered by a user from confusing another user's browser.



Learning PHP and MySQL
Learning PHP and MySQL
ISBN: 0596101104
EAN: 2147483647
Year: N/A
Pages: 135

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net