Learn Apache mod_rewrite: 13 Real-world Examples

Notice: This is a discussion thread for comments about the SitePoint article, Learn Apache mod_rewrite: 13 Real-world Examples.


I know it’s a tiny, inconsequential thing… but under the “forbidden|F” section of “mod_rewrite Flags”, in the title text of “bandwidth”, “date” should read “data”.

(Thanks, Anal-Retentive Man! You’ve saved SitePoint once again!)

how do i build a database?

Nice tutorial - thank you!

You write:

<blockquote>If you’ve shifted files around on your site, changing directory names, try this:

RewriteRule ^/?old_directory/([a-z/.]+)$ new_directory/$1 [R=301,L]

I’ve included the literal dot character (not the “any character” metacharacter) inside the set to allow file extensions. </blockquote>

I think you wrote “/.” when you meant “\.” — you have not escaped the dot character as you say.

This passage is a little unclear:
<blockquote>The {REQUEST_URI} string starts with a / character. Apache changed regex engines when it changed versions, so Apache version 1 requires the leading slash while Apache 2 forbids it!</blockquote>
Are you saying that Apache 1 and 2 each store {REQUEST_URI} differently? Are you saying that although they both store {REQUEST_URI} the same (with a leading slash), Apache 2 directs you to omit leading slashes when writing a pattern rule to match against {REQUEST_URI} because it takes the leading slash for granted? Something else?

Anon,

Apache 1.x: ^/ is required in the DocumentRoot

Apache 2.x: ^ (the leading / will PREVENT a match) is required in DocumentRoot

The two regex engines obviously do things differently (with the {REQUEST_URI} string) so your answer is “yes.”

On the other hand, I believe that http://domain.com%{REQUEST_URI} would be valid in both versions. Now, that’s what I call confusing!

Regards,

DK

Great article.

I have a site where the urls are www(dot)domain(dot)com/article-title(dot)html. I would like to set up the htaccess file to have users be able to type www(dot)domain(dot)com/article-title and be directed to the html file. I imagine there should also be a default rule that directs them to a zero-results url, if possible.

It seems like it should be like number 8 but I’m not sure how to code the cond/rewrite rules. Can you assist?

Bobo,

Good catch but not correct! When INSIDE a range definition like that, the dot character does NOT get escaped so I was allowing both the / and the dot along with lowercase characters.

Delos,

That’s quite simple - like adding the php extension to an extensionless filename (didn’t I have that in the article - or in the article on my site which is linked in my signature?). Here goes … just for you!

RewriteEngine on
RewriteRule ^([a-z]+)$ $1.html [L]

This only allows lowercase characters (do NOT add the dot character like I did in Bobo’s example as it would then match whatever.html) and will IGNORE any domain-only request (the + requires one or more lowercase characters). If you need uppercase, change [a-z]+ to [a-zA-Z]+ and other characters (EXCEPT {space} or RESERVED characters) as required. Post in the Apache forum for more help, if you please.

Regards,

DK

  1. Enforcing secure server only on selected pages => it doesn’t work, I tried several times and nothing

BTW: not “RewriteCond %{ SERVER_PORT } ^443$”
but: “RewriteCond %{SERVER_PORT} ^443$”

long,

Thanks! I hadn’t seen that. Indeed, there are no spaces in an Apache variable!

What’s happening with the request? Did you specify each of your pages within the (x|y|z) atom?

Regards,

DK

Nice Tutorial. It helps me a lot.

M,

Thanks!

Regards,

DK

  1. Creating extensionless links

If your site uses PHP files, and you want to make your links easier to remember – or you just want to hide the file extension, try this:

RewriteRule ^/?([a-z]+)$ $1.php [L]

If you have a mixture of both .html and .php files, you can use RewriteCond statements to check whether the filename with either extension exists as a file:

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]

If the file name exists with the .php extension, that rule will be chosen.

My code is:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://forum.movieat.co.cc/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://forum.movieat.co.cc$ [NC]
RewriteCond %{HTTP_REFERER} !^http://movieat.co.cc/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://movieat.co.cc$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.forum.movieat.co.cc/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.forum.movieat.co.cc$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.movieat.co.cc/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.movieat.co.cc$ [NC]
RewriteRule .*\.(jpg|jpeg|gif|png|bmp)$ http://movieat.co.cc/ [R,NC]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]

It does not work!

Pop,

It looks like you’ve just repeated a coding example from the article then added a list of referrers to PREVENT a redirect.

RewriteEngine on
# If NOT any of these domains ...
# BTW, you DON'T need and DON'T want the end anchors
RewriteCond &#37;{HTTP_REFERER} !^http://forum.movieat.co.cc[COLOR="Red"]/.*$[/COLOR]      [NC]
RewriteCond %{HTTP_REFERER} !^http://forum.movieat.co.cc[COLOR="Red"]$[/COLOR]      [NC]
RewriteCond %{HTTP_REFERER} !^http://movieat.co.cc[COLOR="Red"]/.*$[/COLOR]      [NC]
RewriteCond %{HTTP_REFERER} !^http://movieat.co.cc[COLOR="Red"]$[/COLOR]      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.forum.movieat.co.cc[COLOR="Red"]/.*$[/COLOR]      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.forum.movieat.co.cc[COLOR="Red"][COLOR="Red"]$[/COLOR][/COLOR]      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.movieat.co.cc[COLOR="Red"]/.*$[/COLOR]      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.movieat.co.cc[COLOR="Red"]$ [/COLOR]     [NC]
[COLOR="DarkOrange"]RewriteRule[/COLOR] .*\\.(jpg|jpeg|gif|png|bmp)$ http://movieat.co.cc/ [R,NC]
# all the above is ANDed with ...
RewriteCond %{REQUEST_FILENAME}.html -f  
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]
# The Last flag eliminates the domain exclusion from:
RewriteCond %{REQUEST_FILENAME}.php -f  
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]  

Well, what’s your TEST URL? That makes a difference if you need someone to troubleshoot this for you.

BTW, if you have questions about mod_rewrite, they should be posted in the Apache forum. I didn’t move your post (and my response) as you’d not be likely to find it.

Regards,

DK