I have a question about the RewriteBase directive for mod_rewrite.
On my development server, and the servers I use at work, specifying a RewriteBase tends to make Apache return HTTP 500 errors. So, I leave the RewriteBase directive commented out.
However, some people report that on their Apache setups, a RewriteBase directive is required in order to get URL rewritten properly.
I’m at a loss. Is it simply a difference in Apache versions? Is it something I’m screwing up in the .htaccess? Is there anyway to have .htaccess ignore a RewriteBase directive if it doesn’t need one?
It’s getting to be irritating that some users can’t use my CMS without having to dive into the .htaccess
<IfModule mod_rewrite.c>
SetEnv HTTP_F_URL On
RewriteEngine on
# You may need to set the RewriteBase to point to the root of your
# Fruml installation if you get HTTP 500 errors.
# RewriteBase /dev
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?cmd=$1 [QSA,L]
</IfModule>
Thanks for your advice, support & shoulder to cry on
RewriteBase is only needed to undo the effects of Alias* directives from mod_alias.
Since you don’t seem to be having any of those you don’t need RewriteBase at all.
Btw. You probably have them there because it’s for your CMS and you don’t want to tell people all about how it works, but you know <IfModule mod_rewrite.c>…</IfModule> is bad practice right?
[standard rant #1][indent]The use of “lazy regex,” specifically the :kaioken: EVERYTHING :kaioken: atom, (.*), and its close relatives, is the NUMBER ONE coding error of newbies BECAUSE it is “greedy.” Unless you provide an “exit” from your redirection, you will ALWAYS end up in a loop![/indent][/standard rant #1]
[standard rant #4][indent]The definition of an idiot is someone who repeatedly does the same thing expecting a different result. Asking Apache to confirm the existence of ANY module with an <IfModule> … </IfModule> wrapper is the same thing in the webmaster world. DON’T BE AN IDIOT! If you don’t know whether a module is enabled, run the test ONCE then REMOVE the wrapper as it is EXTREMELY wasteful of Apache’s resources (and should NEVER be allowed on a shared server).[/indent][/standard rant #4]
Sorry, no “standard rant” for the RewriteBase but ScallioXTX covered that pretty well.
Edit:
On second thought, Alias* is a poor description as most webmasters know it as the Redirect series of commands (which Alias is a part of). Look at http://httpd.apache.org/docs/2.2/mod/mod_alias.html for details.
@ standard rant number 1. Whut?
If you want to suggest a better way of rewriting everything to my app’s index.php, please do so. If not, don’t assume that it’s lazy coding. Maybe the app needs to serve everything as it’s hosted outside of the webroot? Thanks!
Also, please note the [L] at the end of the rewrite rule. That means… Last, as in stop rewriting. No endless loops here, I’m not an idiot!
@ standard rant number 4. I shall ignore you calling me an idiot.
Have you ever written software that is distributed to thousands of users with an equal amount of different server setups? If you have, great, please share your uber-code for getting everything to work properly on those thousands of different setups. If not, please shut up unless you have something worthwhile to share.
Perhaps you didn’t mean it, but your post comes over as very hostile. Hence, my own hostile reaction.
@ScallioTXT
Thanks, that’s useful info. And thanks for the pointer about <IfModule/>. I had put them in to supress the 500 errors people get if mod_rewrite isn’t enabled on their server, but I understand why it’s bad practice.
The problem being the part in red.
As dklynn said, this is known as greedy regex and should be avoided at all costs, unless there is really (really!) no alternative.
Indeed, your code isn’t loopy, but that’s because of
RewriteCond %{REQUEST_FILENAME} !-f
Anyway. You want the complete PATH_INFO to be redirected to index.php. Since Apache has a variable for the PATH_INFO, you’d better use that variable instead of matching it using regex and then forwarding the stuff you matched to index.php (which takes more time).
The trick is in the %{REQUEST_URI} part, which contains the full request made to the server (including the leading slash! if you don’t expect that let your app take it out using substring).
The .? is just “match any character zero or one time” which is the same as saying “whatever is here, execute this rule”
Which also the same as using (.*), but this way is more efficient (and more elegant IMHO).
Does that make sense?
Off Topic:
@dklynn, I have to agree with Immerse that the “idiot” part of rant #4 is not the friendliest idea …
Sorry, guys, that “idiot” was part of the old saying (about repeatedly testing the same thing over and over and expecting a different result). It was certainly NOT aimed at Immerse (or any other member, for that matter)! That’s why it’s labeled a “standard rant.”