Example 5-10. Generic browsing code for any query
define(ROWS, 20); // Browse through the $connection by the running $query. // Begin the display of data with row $rowOffset. // Put a header on the page, $pageHeader // Use the array $header[]["header"] for headers on // each <table> column // Use the array $header[]["attrib"] for the names // of the database attributes to show in each column // Use $browseString to prefix an embedded link // to the previous, next, and other pages function browse($scriptName, $connection, $browseString, $rowOffset, $query, $pageHeader, $header) { // (1) Run the query on the database through the // connection if (!($result = @ mysql_query ($query, $connection))) showerror( ); // Find out how many rows there are $rowsFound = @ mysql_num_rows($result); // Is there any data? if ($rowsFound != 0) { // Yes, there is data. // (2a) The "Previous" page begins at the current // offset LESS the number of ROWS per page $previousOffset = $rowOffset - ROWS; // (2b) The "Next" page begins at the current offset // PLUS the number of ROWS per page $nextOffset = $rowOffset + ROWS; // (3) Seek to the current offset if (!mysql_data_seek($result, $rowOffset)) showerror( ); // (4a) Output the header and start a table echo $pageHeader; echo "<table border=\"1\">\n<tr>"; // (4b) Print out the column headers from $header foreach ($header as $element) echo "\n\t<th>" . $element["header"] . "</th>"; echo "\n</tr>"; // (5a) Fetch one page of results (or less if on the // last page) for ( $rowCounter = 0; (($rowCounter < ROWS) && ($row = @ mysql_fetch_array($result)) ); $rowCounter++) { // Print out a row echo "\n<tr>"; // (5b) For each of the attributes in a row foreach($header as $element) { echo "\n\t<td>"; // Get the database attribute name for the // current attribute $temp = $element["attrib"]; // Print out the value of the current // attribute echo $row["$temp"]; echo "</td>"; } // end foreach attribute echo "\n</tr>\n"; } // end for rows in the page // Finish the results table, and start a footer echo "\n</table>\n<br>"; // (6) Show the row numbers that are being viewed echo ($rowOffset + 1) . "-" . ($rowCounter + $rowOffset) . " of "; echo "$rowsFound records found matching " . "your criteria\n<br>"; // (7a) Are there any previous pages? if ($rowOffset > 0) // Yes, so create a previous link echo "\n\t<a href=\"" . $scriptName . "?offset=" . rawurlencode($previousOffset) . "&" . $browseString . "\">Previous</a> "; else // No, there is no previous page so don't // print a link echo "Previous "; // (7b) Are there any Next pages? if (($row != false) && ($rowsFound > $nextOffset)) // Yes, so create a next link echo "\n\t<a href=\"" . $scriptName . "?offset=" . rawurlencode($nextOffset) . "&" . $browseString . "\">Next</a> "; else // No, there is no next page so don't // print a link echo "Next "; } // end if rowsFound != 0 else { echo "<br>No rows found matching your criteria.\n"; } // (7c) Create a link back to the query input page echo "<br><a href=\"" . $scriptName . "\">Back to Search</a><br>"; }
The browse( )
function performs the following steps that are numbered in the comments in Example 5-10:
-
It runs the
$query
through the$connection
. If there are rows returned from the query, the remaining steps are followed. If not, a message is printed. -
It calculates where in the result set a Previous and Next link should be relative to the current offset,
$rowOffset
, that was passed in as a parameter:// (2a) The "Previous" page begins at the current // offset LESS the number of ROWS per page $previousOffset = $rowOffset - ROWS; // (2b) The "Next" page begins at the current offset // PLUS the number of ROWS per page $nextOffset = $rowOffset + ROWS;
The offsets are used later to construct the Previous and Next links.
ROWS
is the numbers of rows per HTML page, and is defined as 20 at the beginning of Example 5-10. -
It then uses
mysql_data_seek( )
to seek in the result set, so that a subsequent call tomysql_fetch_array( )
retrieves row number$rowOffset
. -
The code then prints out the page header and iterates through the
$header
array printing out the associatively accessed"header"
elements as<table>
headings in the first<table>
row. -
The script then retrieves and prints one page of rows from the result set (or, if there is less than a page of rows left to process, as many rows as are available).
A
for
loop retrieves each row, and then aforeach
loop prints out each attribute value in the row according to how it's listed in the$header
associative array elementattrib
. To allow attributes to be referenced associatively by name,mysql_fetch_array( )
is used. -
Having printed the data in a
<table>
, the script prints out the range of rows displayed (from$rowOffset + 1
through$rowOffset + $rowCounter
) and the total number of rows that are retrieved with the query. -
To conclude the function, the script produces the Previous and Next embedded links if they are required, and a Back to Search link. The previous link is created with the following code fragment:
// Are there any previous pages? if ($rowOffset > 0) // Yes, so create a previous link echo "<a href=\"" . $scriptName . "?offset=" . rawurlencode($previousOffset) . "&" . $browseString . "\">Previous</a> "; else // No, there is no previous page so don't // print a link echo "Previous ";
A Previous link is produced only if the first row displayed-
$rowOffset
-isn't row zero; that is, we have just produced a second or later page. The code is a little cryptic, but it produces an embedded hypertext link to$scriptName
, with the parameter$browseString
that provides parameters to another query, and the offset variable set to the value of$previousOffset
calculated earlier.The
rawurlencode( )
function isn't strictly needed here-we are only coding a number-but consistently using it to create URLs with correctly encoded characters is good practice. The Next link is created with similar logic, and the Back to Search link is a static link to$scriptName
without any parameters.
We have now developed a generic browser and applied it to browsing the wines of a region. A similar skeleton to Example 5-9 can be developed to browse customers, inventories, or orders, and all can use the generic browse( )
function.