Jonathon Posted September 21, 2011 Share Posted September 21, 2011 A while ago Larry, you helped me with a .htaccess rule. The full rule was: <IfModule mod_rewrite.c> RewriteEngine on RewriteBase / # Add slashes to the end of everything, if not present: RewriteCond %{REQUEST_URI} !\.[^./]+$ RewriteCond %{REQUEST_URI} !(.*)/$ RewriteRule ^(.*)$ http://localhost/$1/ [R=301,L] # Redirect about/ and about/X to about.php?get=X: RewriteCond %{SCRIPT_FILENAME} !-d RewriteCond %{SCRIPT_FILENAME} !-f RewriteRule ^about/$ about.php RewriteRule ^about/([A-Za-z\+\-]+)/?$ about.php?get=$1 </IfModule> This rule basically added a trailing slash to a URL and mapped URLs to www.example.com/page/ rather than page.php I've set myself a little goal, to take a pagination script and use .htaccess to clean it up. so where a url was previously: www.example.com/page.php?s=30&p=4 /* In my example I'm only using a set of 11 results and display 2 results per page just so I had a decent number of pages to test but didnt have to write loads of Data */ it would look like www.example.com/page/4 So I started quite basic with the .htaccess and thought i'd build it up, so my initial code mapped "test" to "test.php" was: (Here i'm not adding trailing slashes to everything by the way) <IfModule mod_rewrite.c> RewriteEngine on #RewriteRule ^test$ test.php #RewriteRule ^test/([0-9\+\-]+)$ test.php?s=$1&p=$2 </IfModule> But I've started to confuse myself now really. If I type: http://localhost/test -> returns Result 1 + Result 2 :-) http://localhost/test/1 -> returns Result 2 + Result 3 :-) http://localhost/test/2 -> returns Result 3 + Result 4 :-) /* You can see where this is going */ Obviously this is wrong, It would suggest to me that my $_GET['s'] is being mapped as the row to start at from what ever number follows the final slash i.e. /2 Which got me thinking how to correct this and also not mess up my links either. So does anyone have any pointers? Link to comment Share on other sites More sharing options...
banacan Posted September 21, 2011 Share Posted September 21, 2011 If I understand your question, try this: RewriteRule ^test/([0-9]+)/([0-9]+)$ test.php?s=$1&p=$2 Link to comment Share on other sites More sharing options...
Jonathon Posted September 21, 2011 Author Share Posted September 21, 2011 Well that would rewrite to test/2/2 I think. The idea is to just show the page number so test/4 would be page 4 of the results.Appreciate the reply though :-) Link to comment Share on other sites More sharing options...
Larry Posted September 22, 2011 Share Posted September 22, 2011 That answer is what I would have said too. You need both the $s (start) and the $p (number of pages) variables, don't you? So test/10/5 would be a correct URL, in my thinking. Link to comment Share on other sites More sharing options...
Jonathon Posted September 22, 2011 Author Share Posted September 22, 2011 Well yes I agree that that method works. But my intended plan was to just generate a URL of test/4 // To represent page 4 of the results or test/3 // to represent page 3 of the results This is where I started to confuse myself in how to make this happen, because the way I was going about it was wrong. I do need the 's' and 'p' as far as I can see as the whole pagination script runs using these. But I couldn't figure out how to mask them and just display the current page. I shall have another go tomorrow. ** Although it's not tomorrow, I was just thinking if I could pass a 3rd parameter to the URL that would indicate the current page, so text.php?s=2&p=6&c=2 /*Where c was the current page*/ Would that be the way to then remap that query to just display the current page of the results i.e. test/3 Link to comment Share on other sites More sharing options...
Larry Posted September 22, 2011 Share Posted September 22, 2011 If you just pass the page number to be displayed, you can make that work, but every page will need to calculate how many pages there are in order to create all the links. The benefit of passing that information from page to page is the system only needs to determine a total page count once. Also, the current page is implicitly represented by the start value, which equals (current page - 1) * the number of items to display. So if you're displaying 20 items per page, then the start number on page 2 is 20. If you'd rather pass the current page, you can just reverse engineer where to start in the limit clause by subtracting one and multiplying that by the number of items to display. Either way, but you don't need a third variable. Link to comment Share on other sites More sharing options...
Jonathon Posted September 22, 2011 Author Share Posted September 22, 2011 Ok thanks Larry, I shall have a blast at this tomorrow :-) Link to comment Share on other sites More sharing options...
Jonathon Posted September 27, 2011 Author Share Posted September 27, 2011 Right, this is the solution I came up with, just thought i'd put down the solution I came up with rather than leaving it. <?php DEFINE ('DB_USER', ''); DEFINE ('DB_PASSWORD', ''); DEFINE ('DB_HOST', 'localhost'); DEFINE ('DB_NAME', 'test'); $dbc = mysqli_connect (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); mysqli_set_charset($dbc, 'utf8'); // determine what the page number should be or default to page 1 $page = (isset($_GET['page'])) ? (int)$_GET['page'] : 1; // fetch the info to be paged from DB function fetch_results($page, $perPage){ // make $dbc available to function global $dbc; // where to start and how many results per page $start = (int)($page - 1) * $perPage; $perPage = (int)$perPage; // query for results $q = "SELECT `result` FROM `results` LIMIT {$start}, {$perPage}"; $r = mysqli_query($dbc, $q); // put results into avriable to be returned while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) { $result[] = $row['result']; } return $result; } function fetch_total_results(){ // make $dbc available global $dbc; // create query for number of pages needed $q = "SELECT COUNT(`result`) FROM `results`"; $r = mysqli_query($dbc, $q); // put results into variable $totalResult = mysqli_fetch_array($r, MYSQLI_NUM); // return the number of records in DB $totalResults = $totalResult[0]; return $totalResults; } // iterate through results on that page foreach (fetch_results($page, 2) as $data){ echo "<p>{$data}</p>"; } $path = $_SERVER['PHP_SELF']; $path = substr($path, 0, -4); // determine number of pages $totalPages = ceil(fetch_total_results() / 2); for($i = 1; $i <=$totalPages; ++$i) { echo " <a href=\"{$path}/{$i}\">{$i}</a> "; } ?> And this .htaccess file <IfModule mod_rewrite.c> RewriteEngine on RewriteRule ^test$ test.php RewriteRule ^test/([0-9])?$ test.php?page=$1 </IfModule> Things to work on are just outputting 'Next and 'Previous' tags along with not allowing the current page to be a link. Also i'm going to try and automatically remove any trailing slashes. Link to comment Share on other sites More sharing options...
Larry Posted September 27, 2011 Share Posted September 27, 2011 Thanks for sharing, Jonathon, and kudos for the work you've done! Link to comment Share on other sites More sharing options...
Jonathon Posted September 27, 2011 Author Share Posted September 27, 2011 No problem, thanks for the pointers :-) Link to comment Share on other sites More sharing options...
Recommended Posts