Forum Moderators: phranque
My site makes use of PHP however I have made the following rewrite rule that allows me to link directly to .html pages:
RewriteEngine On
RewriteBase /forums
#
RewriteRule ^(.*)\.html $1.php [L]
Now I would like any request for a .php page to return a 404.
Trying
RewriteRule ^(.*)\.php $.h [R=404,S=1]
Either before or after the above rule didn't help. Any advice (or simply a solution) would be greatly appreciated.
[edited by: jdMorgan at 1:13 pm (utc) on Oct. 8, 2009]
[edit reason] Formatting [/edit]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/#?\ ]+/)*[^.#?\ ]+\.php(#[^?\ ]*)?(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php$ http://www.example.com/$1.html [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/#?\ ]+/)*[^.#?\ ]+\.php(#[^?\ ]*)?(\?[^\ ]*)?\ HTTP/
RewriteRule ^([^/]+/)*[^.]+\.php$ - [R=404,L]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/#?\ ]+/)*[^.#?\ ]+\.php(#[^?\ ]*)?(\?[^\ ]*)?\ HTTP/
RewriteRule ^([^/]+/)*[^.]+\.php$ /path-which-will-never-exist.html [L]
Tweaking the rules ever so slightly got it to work the way it should.
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/#?\ ]+/)*[^.#?\ ]+\.php(#[^?\ ]*)?(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php$ $1.notfound [R=404] RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/#?\ ]+/)*[^.#?\ ]+\.html(#[^?\ ]*)?(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.html$ $1.php [L]
Keep in mind that server config code must be considered in terms of its effects on both server operation *and* search engine listings; We see Webmasters committing 'virtual SE suicide' on an almost daily basis, and we can only hope that you're not the latest... :)
[added]
Your second rule is unnecessarily complex, and contains an exploitable security hole. You can delete the RewriteCond entirely, and you should change the rule to:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/#?\ ]+/)*[^.#?\ ]+\.html(#[^?\ ]*)?(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.html$ [b]/$[/b]1.php [L]
[/added] Jim
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/#?\ ]+/)*[^.#?\ ]+\.php(#[^?\ ]*)?(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php$ [b]/$[/b]1.notfound [R=404]
#
RewriteRule ^(([^/]+/)*[^.]+)\.html$ [b]/$[/b]1.php [L]
The purpose of the RewriteCond on the first rule is to make sure that requests rewritten from ".html" paths to ".php" paths by the second rule do not then get subsequently 404ed by the first rule. We check the original client request to confirm that it is the client asking for a ".php" file, rather than an internal request that has already been rewritten by the second rule.
This same kind of test is not necessary on the second rule because we always want to deliver content using PHP scripts whenever a ".html" resource is requested, and because this rule is second (it follows the first rule), you "won't be able to reach" the second rule until the first rule has already been invoked.
Jim