I've just started out trying to teach myself PHP. While jumping around in the chapters of the PHP book I bought, I came across this script (code to follow) that reads records from the database and then display them in a table. It paginates the records, so you can specify how many to show at a time and the links are given in the form of view_users.php?s=3p=10 Everything works perfectly fine, but it got me thinking on how to add error handling for handling the links. There's nothing to stop the user from changing the URL and the values passed to 's' (defines which record to start at) and 'p' the number of pages to display. There's also no checks in place to ensure that only numeric data is passed to the variables. This is really bugging me. I know what's wrong, but I don't know how to fix it and it will definitely keep me up wondering about it. Any ideas? <?php # Script 9.4 - #4 // This script retrieves all the records from the users table. // This version paginates the query results. $page_title = 'View the Current Users'; include ('includes/header.html'); echo '<h1>Registered Users</h1>'; require_once ('../mysqli_connect.php'); // Number of records to show per page: $display = 10; // Determine how many pages there are... if (isset($_GET['p']) && is_numeric($_GET['p'])) { // Already been determined. $pages = $_GET['p']; } else { // Need to determine. // Count the number of records: $q = "SELECT COUNT(user_id) FROM users"; $r = @mysqli_query ($dbc, $q); $row = @mysqli_fetch_array ($r, MYSQLI_NUM); $records = $row[0]; // Calculate the number of pages... if ($records > $display) { // More than 1 page. $pages = ceil ($records/$display); } else { $pages = 1; } } // End of p IF. // Determine where in the database to start returning results... if (isset($_GET['s']) && is_numeric($_GET['s'])) { $start = $_GET['s']; } else { $start = 0; } // Make the query: $q = "SELECT last_name, first_name, DATE_FORMAT(registration_date, '%M %d, %Y') AS dr, user_id FROM users ORDER BY registration_date ASC LIMIT $start, $display"; $r = @mysqli_query ($dbc, $q); // Table header: echo '<table align="center" cellspacing="0" cellpadding="5" width="75%"> <tr> <td align="left"><b>Edit</b></td> <td align="left"><b>Delete</b></td> <td align="left"><b>Last Name</b></td> <td align="left"><b>First Name</b></td> <td align="left"><b>Date Registered</b></td> </tr> '; // Fetch and print all the records.... $bg = '#eeeeee'; // Set the initial background color. while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) { $bg = ($bg=='#eeeeee' ? '#ffffff' : '#eeeeee'); // Switch the background color. echo '<tr bgcolor="' . $bg . '"> <td align="left"><a href="edit_user.php?id=' . $row['user_id'] . '">Edit</a></td> <td align="left"><a href="delete_user.php?id=' . $row['user_id'] . '">Delete</a></td> <td align="left">' . $row['last_name'] . '</td> <td align="left">' . $row['first_name'] . '</td> <td align="left">' . $row['dr'] . '</td> </tr> '; } // End of WHILE loop. echo '</table>'; mysqli_free_result ($r); mysqli_close($dbc); // Make the links to other pages, if necessary. if ($pages > 1) { // Add some spacing and start a paragraph: echo '<br /><p>'; // Determine what page the script is on: $current_page = ($start/$display) + 1; // If it's not the first page, make a Previous button: if ($current_page != 1) { echo '<a href="view_users.php?s=' . ($start - $display) . '&p=' . $pages . '">Previous</a> '; } // Make all the numbered pages: for ($i = 1; $i <= $pages; $i++) { if ($i != $current_page) { echo '<a href="view_users.php?s=' . (($display * ($i - 1))) . '&p=' . $pages . '">' . $i . '</a> '; } else { echo $i . ' '; } } // End of FOR loop. // If it's not the last page, make a Next button: if ($current_page != $pages) { echo '<a href="view_users.php?s=' . ($start + $display) . '&p=' . $pages . '">Next</a>'; } echo '</p>'; // Close the paragraph. } // End of links section. include ('includes/footer.html'); ?> PHP:
Hi You already have a feature to check if the values are numeric. Look at the is_numeric function in your script. As far as stopping people from changing the urls directly. You can grab your http referrer and ensure that only if it is your site url (use preg_match) (in if statement) must the results be displayed. Hope this helps.
Thanks. I did miss the is_numeric bit when I first went through the code, but found it on a second look. In any case, I've found a work around that should be good enough. Setting a "max-pages" constant and checking if the number is larger than the "max-pages", if it is then you just find the real number of pages to display. The downside is that the value needs to be set manually once your content gets close to exceeding the number of pages.