Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I've been trying to create some rewrite rules for the last few hours and I'm failing miserably. If anyone could help, I would be extremely grateful.

I have four different types of rewrites I'm trying to do with multiple parameters in each.

First, the URLs with no modification:

http://www.example.com/index.php?p=/category/page-slug&pn=2/
http://www.example.com/index.php?p=/category/&f=feed/rss (feed, feed/, feed/rss, feed/atom are the only possible values for the f parameter)
http://www.example.com/index.php?p=tag&t=tag-one+tag-two+-tag-three&pn=2/
http://www.example.com/index.php?p=search&q=search+query+goes+here&pn=2/

Next, what I'd like to be able to type into the browser instead:

http://www.example.com/category/page-slug/2/
http://www.example.com/category/feed/rss 
http://www.example.com/tags/tag-one+tag-two+-tag-three/2/
http://www.example.com/search/search+query+goes+here/2/

Finally, what I've tried, along with countless variations:

RewriteRule ^([a-zA-Z0-9-/+]+)([0-9]+)$ index.php?p=/$1&pn=$2/ [L]
RewriteRule ^([a-zA-Z0-9-/+]+)([a-zA-Z/]+)$ index.php?p=/$1&f=$2/ [L]
RewriteRule ^([a-zA-Z0-9-/+]+)([a-zA-Z/]+)([0-9]+)$ index.php?p=/$1&t=$2&pn=$3/ [L]
RewriteRule ^([a-zA-Z0-9-/+]+)([a-zA-Z/]+)([0-9]+)$ index.php?p=/$1&q=$2&pn=$3/ [L]

I'm able to handle just the p parameter fine using:

RewriteRule ^([a-zA-Z0-9-/+]+)$ index.php?p=/$1 [L]

However, everything else has completely escaped me. I feel like I'm close, but it's incredibly frustrating because I don't know of any way to narrow the problem down. It either works or it doesn't. Thanks in advance.

share|improve this question

1 Answer 1

up vote 2 down vote accepted

Here you go: (note that this strips the trailing "/" for pn variables)

RewriteEngine on
RewriteBase /

RewriteRule ^category/(.*)/([0-9]+) index.php?p=/category/$1&pn=$2 [L]
RewriteRule ^category/feed(.*) index.php?p=/category/&f=feed$1 [L]
RewriteRule ^tags/(.*)/([0-9]+)/ index.php?p=$1&pn=$2 [L]
RewriteRule ^search/(.*)/([0-9]+)/ index.php?p=search&q=$1&pn=$2 [L]

... and a PHP file to simplify testing:

<html><head><title>Testing</title></head><body><pre><?php

var_dump($_GET);

echo "\r\n";

var_dump($_SERVER);

?></pre></body></html>

Update: If you plan to have variable category names and you cannot guarantee that the / character will work as a separator, you should consider handling URI parsing within your application itself.

Example rewrite directives:

RewriteEngine on
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php [L,QSA]

Example PHP file:

<?php

  $uri = $_SERVER['REQUEST_URI'];
  $uri_array = explode( "/", $uri );

  switch ( $uri_array[0] ) {
    case '':
      /* serve index page */
    break;
    case 'feed':
      switch ( $uri_array[1] ) {
          case 'atom':
              /* serve atom feed */
          break;
          case 'rss':
              /* serve RSS feed */
          break;
          default:
              /* default feed behavior */
          break;
      }
    break;
    case 'tags':
        $tags = ($uri_array[1]) ? $uri_array[1] : '';
        $page_number = ($uri_array[2]) ? $uri_array[2] : 1;
        /* tag display behavior */
    break;
    default:
        $category = ($uri_array[1]) ? $uri_array[1] : '';
        $page_number = ($uri_array[2]) ? $uri_array[2] : 1;
        /* category lookup behavior + return 404 if category not found */
    break;
  }
?>
share|improve this answer
    
Thanks danlefree. Your php snippet actually helped me discover that the 'p' parameter is picking up the page number as well. I think that's probably the heart of my problem because I've tried code very similar to what you've posted. Any ideas? I'm a little stumped because 'p' is completely dynamic (including the category part) and could include a number. –  VirtuosiMedia Dec 9 '10 at 8:37
    
As an example, my unaltered URL is example.com/index.php?p=/business/articles/&pn=2/. Shortened, I'd like it to be example.com/business/articles/2/. However, instead of $_GET['p'] being equal to 'business/articles/' and $_GET['pn'] = '2/', $_GET['p'] is 'business/articles/2/' and $_GET['pn'] doesn't exist. I'm not sure how I would separate those, especially if p can contain [a-zA-Z0-9-/]. –  VirtuosiMedia Dec 9 '10 at 8:42
    
@VirtuosiMedia - Your regexp needs to have reliable boundaries (i.e. category name, use of /, etc) ... otherwise it makes more sense to put your URI->application behavior parsing into the application itself. –  danlefree Dec 10 '10 at 7:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.