Problem: mod_rewrite path point of reference seems to be changing

The following directory structure will be the basis of my question:

_css (this is a folder)
public (this is a folder)

Open in new window

Both _css and public folders are sibling folders.

Here's how my .htaccess file looks like:

DirectoryIndex public/login.php
RewriteEngine On
RewriteRule ^login/*$ public/login.php [L]
RewriteRule ^login/([^/.]_)/?$ public/login.php?a=$1 [L]

Open in new window

Let's say my domain name is

When I use the URL, the DirectoryIndex knows to redirect to 'public/login.php'. To make the styles in my style sheet take effect, I have to define my style sheet within 'login.php' as:

<link rel="stylesheet" [b]href="_css/main.css"[/b] />

Open in new window

But notice, the path point of reference is the application root and not the 'public' folder; otherwise, I would've had to define the path to my style sheet as ../_css/main.css instead of _css/main.css.

Now let's say I use this URL:, the bottom RewriteRule would kick in and redirect me to public/login?a=logout. But I noticed all the style settings in login.php would be gone! Somehow, to make it look normal, I'd have to redefine the path to my style sheet as '../_css/main.css' instead of the original '_css/main.css'. What this tells me is that Apache now thinks its path point of reference is in the public folder instead of the application root as it did before, causing it to be unable to find my 'main.css'.

This is kind of driving me crazy because I don't know how mod_rewrite determines its path point of reference. In one situation, it's the application root directory, then in another situation, it's using the 'public' subdirectory of the application root. To the more experienced people on mod_rewrite, I would appreciate some sage advise on how you overcome this behavior.

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

elepilAuthor Commented:
Oh, my .htaccess looks like this: (It was missing the RewriteBase before)

DirectoryIndex public/login.php
RewriteEngine On
RewriteBase /mySite/
RewriteRule ^login/*$ public/login.php [L]
RewriteRule ^login/([^/.]_)/?$ public/login.php?a=$1 [L]

Open in new window

Steve BinkCommented:
The behavior you are describing is not confusing at all.  In fact, it is well-documented, and rather intuitive once you are familiar with how mod_rewrite works.

If you request, the DirectoryIndex will search for public/login.php to serve as the response for "/".  In this case, the URL requested is still "/" (or "").  That hasn't changed.  The %{SCRIPT_FILENAME} value in mod_rewrite should change, but that's a different conversation.  In any case, the application of DirectoryIndex does not change the request Apache received, so your "point of reference" is still the root.

If you request, the actual request is "/login".  Here, your first RewriteRule rewrites the request to "public/login.php".  That changes the URL being requested, which in turn will change a fair number of things about Apache's environment.  This especially important point here is graphically demonstrated in Figure 1 of mod_rewrite's technical details documentation.   Note how an internal redirect is being pushed back into "Apache receives URI".  

Regarding your CSS reference issue, is there a reason you cannot use an absolute path, e.g., href="/_css/main.css"?  You did mention your RewriteBase is one level down, but that can also be managed with an internal rewrite.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
elepilAuthor Commented:
To Steve Binks:

Thank you for responding, Steve. You said:

Regarding your CSS reference issue, is there a reason you cannot use an absolute path, e.g., href="/_css/main.css"?
That was one of the first things I tried, and it's driving me crazy why it's not working! In fact, specifying an absolute path makes it fail at ALL times! I eventually had to resign to the thought that maybe it's the mod_rewrite interfering in some bizarre way, even though I couldn't figure out exactly how.

I was looking over the flowchart you specified in the Apache documentation, and while it is clear that it's checking if the URI changed, it does not explicitly tell me how it changes the "point of reference". Let me pick your brain on this a little -- would it be fair to say that if a RewriteRule rewrites the URL to public/login.php, the new point of reference will then change to the folder of the target document (which in this case would be the 'public' folder)? So if a RewriteRule rewrites the URL to core/logout.php, would the new "point of reference" now be the 'core' subfolder? Would I still be off in assuming that?
Protecting & Securing Your Critical Data

Considering 93 percent of companies file for bankruptcy within 12 months of a disaster that blocked access to their data for 10 days or more, planning for the worst is just smart business. Learn how Acronis Backup integrates security at every stage

elepilAuthor Commented:
To Steve Binks:

I think I know why providing an absolute path for my CSS files are failing, and I found this out through Netbeans. Here is the warning Netbeans is showing:

Failed to load resource: the server responded with a status of 404 (Not Found) (10:38:57:855 | error, network)
  at http://localhost/_css/main.css

For some reason, even though I specified my web root as C:\xampp\htdocs\myApp in my Netbeans project settings, Apache is treating C:\xampp\htdocs as my web root and is assuming that's where _css is, which it's not. But aside from my project settings in Netbeans, I don't know any other way to specify my web root.

Do you have any comments/suggestions?
Steve BinkCommented:
In your Apache conf file, set your DocumentRoot to "c:/xampp/htdocs/myApp".

Your other observations on the "point of reference" are correct.  When the URL is rewritten, mod_rewrite will resubmit the request back into Apache using the new URL.  This is effectively a new request, and restarts the entire process.  So, if you're changing directories, you can expect the new request to have its environment set to the context of the new directory.
elepilAuthor Commented:
Steve, if I set my Apache conf file to C:/xampp/htdocs/myApp, that would compromise all other apps I have in C:/xampp/htdocs, wouldn't it?

I always assumed that the purpose for an IDE like Netbeans in asking one's application root is so that it would know how to properly "path" pages of the application.

I probably will open up another question on how to resolve this, I'm interested in how other Netbeans users address this.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Apache Web Server

From novice to tech pro — start learning today.