Jump to content



Photo

Regex Query


  • Please log in to reply
9 replies to this topic

#1 Jonathon

Jonathon

    Advanced Member

  • Members
  • PipPipPip
  • 1,025 posts

Posted 21 September 2011 - 3:27 PM

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?
  • 0

#2 banacan

banacan

    Member

  • Members
  • PipPip
  • 48 posts

Posted 21 September 2011 - 3:51 PM

If I understand your question, try this:

RewriteRule ^test/([0-9]+)/([0-9]+)$ test.php?s=$1&p=$2
  • 0

#3 Jonathon

Jonathon

    Advanced Member

  • Members
  • PipPipPip
  • 1,025 posts

Posted 21 September 2011 - 6:07 PM

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 :-)
  • 0

#4 Larry

Larry

    Administrator/Writer

  • Administrators
  • 3,964 posts
  • LocationState College, PA (USA)

Posted 21 September 2011 - 7:04 PM

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.
  • 0

#5 Jonathon

Jonathon

    Advanced Member

  • Members
  • PipPipPip
  • 1,025 posts

Posted 21 September 2011 - 7:51 PM

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
  • 0

#6 Larry

Larry

    Administrator/Writer

  • Administrators
  • 3,964 posts
  • LocationState College, PA (USA)

Posted 21 September 2011 - 8:52 PM

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.
  • 0

#7 Jonathon

Jonathon

    Advanced Member

  • Members
  • PipPipPip
  • 1,025 posts

Posted 21 September 2011 - 10:15 PM

Ok thanks Larry, I shall have a blast at this tomorrow :-)
  • 0

#8 Jonathon

Jonathon

    Advanced Member

  • Members
  • PipPipPip
  • 1,025 posts

Posted 27 September 2011 - 9:47 AM

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.
  • 0

#9 Larry

Larry

    Administrator/Writer

  • Administrators
  • 3,964 posts
  • LocationState College, PA (USA)

Posted 27 September 2011 - 11:23 AM

Thanks for sharing, Jonathon, and kudos for the work you've done!
  • 0

#10 Jonathon

Jonathon

    Advanced Member

  • Members
  • PipPipPip
  • 1,025 posts

Posted 27 September 2011 - 12:50 PM

No problem, thanks for the pointers :-)
  • 0