Jump to content
Larry Ullman's Book Forums

Regex Query


Recommended Posts

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

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

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

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

 Share

×
×
  • Create New...