7

This is what I've tried till now:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.*) $1.php [L]

RewriteCond %{QUERY_STRING} ^id=([0-9]{1})$
RewriteRule ^article\.php$ /article/%1 [L]

Basically, the first set of rules converts the URLs from something.php to something.

The second set of rules is supposed to replace anything that has article.php?id=NUMBER in it into /article/NUMBER.

Apache reports:

AH00124: Request exceeded the limit of 10 internal redirects due to probable 
configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary.
anubhava
  • 761,203
  • 64
  • 569
  • 643
hytromo
  • 1,501
  • 2
  • 27
  • 57

2 Answers2

2

The second set of rules is supposed to replace anything that has article.php?id=NUMBER in it into /article/NUMBER.

I believe you have rules reversed.

Try this code instead:

RewriteEngine On
RewriteBase /mellori/

# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} /article\.php\?id=([^\s&]+) [NC]
RewriteRule ^ article/%1? [R=302,L]

# internally rewrites /article/123 to article.php?id=123
RewriteRule ^article/([0-9]+)$ article.php?id=$1 [L,NC,QSA]

# PHP hiding rule
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    This kind of works... But not completely... Requested: `http://localhost/mellori/article.php?id=33` and got `http://localhost/opt/lampp/htdocs/mellori/article/33` which is a full path in my system, not from webroot (and thus it results in an object not found error) – hytromo Nov 12 '13 at 11:22
  • Is this .htaccess located in DOCUMENT_ROOT or in some sub-dir? – anubhava Nov 12 '13 at 11:37
  • The webroot is at /opt/lampp/htdocs/ and the .htaccess is located at /opt/lampp/htdocs/mellori – hytromo Nov 12 '13 at 11:39
  • This seems to work well for me. However, how could this be modified to handle both `http://localhost/opt/lampp/htdocs/mellori/article/33` and `http://localhost/opt/lampp/htdocs/mellori/article/33/` (please note trailing `/`. – Eric K Jun 10 '14 at 18:20
  • Make trailing slash optional here: `RewriteRule ^article/([0-9]+)/?$` – anubhava Jun 10 '14 at 18:25
0

You need to make sure when you match against ^article\.php$ that it is from the actual request and not the URI that's been rewritten by the previous rule. So you can either append an ENV check for an internal redirect, or match against `%{THE_REQUEST}.

Your choice:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^id=([0-9]{1})$
RewriteRule ^article\.php$ /article/%1 [L]

or

RewriteCond %{THE_REQUEST} \ /+article\.php\?id=([0-9]{1})(\ |$)
RewriteRule ^ /article/%1 [L]
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • 1
    Nope... I still get the redirect problem. This is my full .htaccess file, without the documents that work as error (404, 403 etc) handlers: http://paste.ubuntu.com/6386963/ Of course I restarted apache after editing the file and please note that the article.php file is under a subdirectory of webroot (let's call it 'subdir'), if this has anything to do with... – hytromo Nov 09 '13 at 09:59