2

Basically you can visit /stats.php?player=name by simply typing in https://domain.com/@name and it works perfectly. But I also need the old /stats.php?player=name links to redirect to https://domain.com/@name.

How do I do this? Below is my .htaccess file.

<IfModule mod_rewrite.c>
ErrorDocument 404 /404.php
RewriteRule ^@(\w+)$ stats.php?player=$1
Options +FollowSymlinks
Options -MultiViews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
</ifModule>
2

In this case, where you are already rewriting the "pretty" URL to the "ugly/real" URL you can redirect the ugly URL to the pretty URL by checking against THE_REQUEST. This contains the original HTTP request, before any rewriting has occurred. Otherwise you are in danger of creating a rewrite loop when you rewrite back to the ugly URL. For example:

RewriteCond %{THE_REQUEST} \?player=(\w+)\ HTTP
RewriteRule ^stats\.php$ /@%1? [R=301,L]

External redirects should generally come before internal rewrites.

Checking for "stats.php" in the RewriteRule pattern, rather that in the RewriteCond directive lessens the load on the server by not processing every single request (the RewriteRule is processed first). %1 refers to the first parenthesised sub pattern in the RewriteCond pattern. And the trailing ? (an empty query string) essentially removes the query string from the rewritten substitution.

I would also append the L flag and make your current RewriteRule root-relative by prefixing with a slash (assuming this file is in the root of your site). Relative URLs can be problematic in .htaccess files:

RewriteRule ^@(\w+)$ /stats.php?player=$1 [L]

Also, move the Options and RewriteEngine directives to the top:

ErrorDocument 404 /404.php

Options +FollowSymlinks
Options -MultiViews

RewriteEngine On

RewriteCond %{THE_REQUEST} \?player=(\w+)\ HTTP
RewriteRule ^stats\.php$ /@%1? [R=301,L]

RewriteRule ^@(\w+)$ /stats.php?player=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ /$1.php [NC,L]

(I've also snuck a slash in the last RewriteRule substitution as well. If you use relative URLs then you should also specify a RewriteBase directive.)

The check for <IfModule mod_rewrite.c> is also probably unnecessary. Unless you specifically only want to set an ErrorDocument and Options if this module is available?!

  • Hey thanks so much for your informative post - I had high hopes for it, but sadly I get a redirect loop on stats.php while this .htaccess is uploaded. Does it have anything to do with the site being HTTPS? – Dalton Edwards Jan 20 '15 at 22:43
  • I noticed it takes you to domain.com/@name?player=name – Dalton Edwards Jan 20 '15 at 22:48
  • Ah yes - oops! It needs a single ? on the end of the RewriteRule substitution in order to chop off the query string! I've also appended an [L] flag to your existing rewrite. I've updated the answer. – MrWhite Jan 20 '15 at 22:53
  • Hey thanks! :) Do I re-add the <IfModule mod_rewrite.c> so that my 404 page works again (404.php)? it currently redirects to index.php now. – Dalton Edwards Jan 20 '15 at 22:57
  • The <IfModule check is really superfluous for mod_rewrite. If mod_write isn't installed, the directives are simply ignored anyway and presumably it is already installed on your server or nothing would be working? (TBH it's a bit of a puzzle why it is so often used.) I can't see off hand why your 404 page is being redirected? It does exist? This is presumably for when you access a non existent page, rather than accessing the 404.php page directly? – MrWhite Jan 20 '15 at 23:15

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.