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/&f=feed/rss (feed, feed/, feed/rss, feed/atom are the only possible values for the f parameter)

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


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.


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:



echo "\r\n";



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:


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

  switch ( $uri_array[0] ) {
    case '':
      /* serve index page */
    case 'feed':
      switch ( $uri_array[1] ) {
          case 'atom':
              /* serve atom feed */
          case 'rss':
              /* serve RSS feed */
              /* default feed behavior */
    case 'tags':
        $tags = ($uri_array[1]) ? $uri_array[1] : '';
        $page_number = ($uri_array[2]) ? $uri_array[2] : 1;
        /* tag display behavior */
        $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 */
| 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

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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