Figure 10.2 The results of searching the database for books about Java arepresented in a Web page using the results.php script.. Checking and Filtering Input Data We begin our script by
Trang 1Figure 10.2 The results of searching the database for books about Java are
presented in a Web page using the results.php script.
The Basic Steps in Querying a Database from the Web
In any script used to access a database from the Web, you will follow some basic steps:
1 Check and filter data coming from the user
2 Set up a connection to the appropriate database
3 Query the database
4 Retrieve the results
5 Present the results back to the user
These are the steps we have followed in the script results.php, and we will go through each of them in turn
Checking and Filtering Input Data
We begin our script by stripping any whitespace that the user might have inadvertently entered at the beginning or end of his search term.We do this by applying the function
trim()to $searchterm
$searchterm=trim($searchterm);
Our next step is to verify that the user has entered a search term and search type Note that we check he entered a search term after trimming whitespace from the ends
of $searchterm Had we arranged these lines in the opposite order, we could get
Trang 2228 Chapter 10 Accessing Your MySQL Database from the Web with PHP
situations where a user’s search term was not empty, so it did not create an error mes-sage, but it was all whitespace, so it was deleted by trim():
if (!$searchtype || !$searchterm) {
echo 'You have not entered search details Please go back and try again.'; exit;
}
You will notice that we’ve checked the $searchtypevariable even though in this case it’s coming from an HTML SELECT.You might ask why we bother checking data that has to be filled in It’s important to remember that there might be more than one inter-face to your database For example, Amazon has many affiliates who use their search interface Also, it’s sensible to screen data in case of any security problems that can arise because of users coming from different points of entry
Also, when you are going to use any data input by a user, it is important to filter it appropriately for any control characters As you might remember, in Chapter 4, “String Manipulation and Regular Expressions,” we talked about the functions addslashes()
and stripslashes().You need to use addslashes()when submitting any user input to
a database such as MySQL and stripslashes()when returning output to the user who has had control characters slashed out
In this case we have used addslashes()on the search terms:
$searchterm = addslashes($searchterm);
We have also used stripslashes()on the data coming back from the database None
of the data we have entered by hand into the database has any slashes in it—however, it also doesn’t have any control characters in it.The call to stripslashes()will have no effect As we build a Web interface for the database, chances are we will want to enter new books in it, and some of the details entered by a user might contain these charac-ters.When we put them into the database, we will call addslashes(), which means that
we must call stripslashes()when taking the data back out.This is a sensible habit to get into
We are using the function htmlspecialchars()to encode characters that have spe-cial meanings in HTML Our current test data does not include any ampersands (&), less than (<), greater than (>), or double quote (“) symbols, but many fine book titles con-tain an ampersand By using this function, we can eliminate future errors
Setting Up a Connection
We use this line in our script to connect to the MySQL server:
@ $db = mysql_pconnect('localhost', 'bookorama', 'bookorama123');
We have used the mysql_pconnect()function to connect to the database.This function has the following prototype:
Trang 3resource mysql_pconnect( [string host [:port] [:/socketpath] [,
string user [, string password]]] );
Generally speaking, you will pass it the name of the host on which the MySQL server is running, the username to login as, and the password of that user All of these are
option-al, and if you don’t specify them, the function uses some sensible defaults—localhost for the host, the username that the PHP process runs as, and a blank password
The function returns a link identifier to your MySQL database on success (which you ought to store for further use) or false on failure.The result is worth checking as none of the rest of code will work without a valid database connection.We have done this using the following code:
if (!$db) {
echo 'Error: Could not connect to database Please try again later.';
exit;
}
An alternative function that does almost the same thing as mysql_pconnect()is
mysql_connect().The difference is that mysql_pconnect()returns a persistent
connec-tion to the database
A normal connection to the database will be closed when a script finishes execution,
or when the script calls the mysql_close()function A persistent connection remains open after the script finishes execution and cannot be closed with the mysql_close()
function
You might wonder why we would want to do this.The answer is that making a con-nection to a database involves a certain amount of overhead and therefore takes some time.When mysql_pconnect()is called, before it tries to connect to the database, it will automatically check if there is a persistent connection already open If so, it will use this one rather than opening a new one.This saves time and server overhead
It is also worth noting that persistent connections don’t persist if you are running PHP as a CGI (Each call to a PHP script starts a new instance of PHP and closes it when the script finishes execution.This also closes any persistent connections.) Bear in mind that there is a limit to the number of MySQL connections that can exist at the same time.The MySQL parameter max_connectionsdetermines what this limit is.The purpose of this parameter and the related Apache parameter MaxClientsis
to tell the server to reject new connection requests rather than allowing machine resources to be all used at busy times or when software has crashed
You can alter both of these parameters from their default values by editing the con-figuration files.To set MaxClientsin Apache, edit the httpd.conf file on your system.To set max_connections for MySQL, edit the file my.conf
If you use persistent connections and nearly every page in your site involves database access, you are likely to have a persistent connection open for each Apache process.This can cause a problem if you leave these parameters set to their default values By default, Apache allows 150 connections, but MySQL only allows 100 At busy times, there might
Trang 4230 Chapter 10 Accessing Your MySQL Database from the Web with PHP
not be enough connections to go around Depending on the capabilities of your hard-ware, you should adjust these so that each Web server process can have a connection
Choosing a Database to Use
You will remember that when we are using MySQL from a command line interface, we need to tell it which database we plan to use with a command such as
use books;
We also need to do this when connecting from the Web.We perform this from PHP with a call to the mysql_select_db()function, which we have done in this case as fol-lows:
mysql_select_db('books');
The mysql_select_db()function has the following prototype:
bool mysql_select_db(string database, [resource database_connection] );
It will try to use the database called database You can also optionally include the database
link you would like to perform this operation on (in this case $db), but if you don’t specify it, the last opened link will be used If you don’t have a link open, the default one will be opened as if you had called mysql_connect()
Querying the Database
To actually perform the query, we can use the mysql_query()function Before doing this, however, it’s a good idea to set up the query you want to run:
$query = "select * from books where ".$searchtype." like '%".$searchterm."%'";
In this case, we are searching for the user-input value ($searchterm) in the field the user specified ($searchtype).You will notice that we have used like for matching rather than equal—it’s usually a good idea to be more tolerant in a database search
Tip
It’s important to realize that the query you send to MySQL does not need a semicolon on the end of it, unlike a query you type into the MySQL monitor.
We can now run the query:
$result = mysql_query($query);
The mysql_query()function has the following prototype:
resource mysql_query(string query, [resource database_connection] );
You pass it the query you want to run, and optionally, the database link (again, in this case $db) If not specified, the function will use the last opened link If there isn’t one, the function will open the default one as if you had called mysql_connect()
Trang 5This function returns a result identifier (that allows you to retrieve the query results)
on success and false on failure.You should store this (as we have in this case in $result)
so that you can do something useful with it
Retrieving the Query Results
A variety of functions are available to break the results out of the result identifier in dif-ferent ways.The result identifier is the key to accessing the zero, one, or more rows returned by the query
In our example, we have used two of these:mysql_num_rows()and
mysql_fetch_array() The function mysql_num_rows()gives you the number of rows returned by the query.You should pass it the result identifier, like this:
$num_results = mysql_num_rows($result);
It’s useful to know this—if we plan to process or display the results, we know how many there are and can now loop through them:
for ($i=0; $i <$num_results; $i++) {
// process results }
In each iteration of this loop, we are calling mysql_fetch_array().The loop will not execute if no rows are returned.This is a function that takes each row from the resultset and returns the row as an associative array, with each key an attribute name and each value the corresponding value in the array:
$row = mysql_fetch_array($result);
Given the associative array $row, we can go through each field and display them appro-priately, for example:
echo '<br />ISBN: ';
echo stripslashes($row['isbn']);
As previously mentioned, we have called stripslashes()to tidy up the value before displaying it
There are several variations on getting results from a result identifier Instead of an associative array, we can retrieve the results in an enumerated array with
mysql_fetch_row(), as follows:
$row = mysql_fetch_row($result);
The attribute values will be listed in each of the array values $row[0],$row[1], and so on
You could also fetch a row into an object with the mysql_fetch_object()function: