12

Let's say I have thiswww.example.com site structure:

/srv/http/
/srv/http/site/index.php
/srv/http/site/stuff.php

I want the following rewrites/redirects to happen:

www.example.com/index.php -> redirects to -> www.example.com/site/index.php -> but the user sees -> www.example.com/index.php

www.example.com/stuff.php -> redirects to -> www.example.com/site/stuff.php -> but the user sees -> www.example.com/stuff.php

In general, everything after www.example.com/ redirects to www.example.com/site/. But the user sees the original URL in the browser.

I've looked around on the internet but haven't managed to figure out what to use in this particular situation.

I tried rewriting everything:

RewriteEngine On
RewriteRule ^$ /site [L]

but index.php disappears and www.example.com/site/ is shown to the user.

How can I use .htaccess to solve this problem?

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • why don't you just move the DocumentRoot to .../site ? – guido Oct 16 '14 at 13:15
  • Are any of the below answers working for you? – anubhava Oct 16 '14 at 20:31
  • That is strange. If you are not using the [R] flag, the browser should not be redirected, so `www.example.com/site/` should not be shown to the user. I am tempted to think something else kicks in before your rewrite, like a `ErrorDocument 404` rule - since the /index.php and /stuff.php don't really exist on that location – commonpike Apr 08 '16 at 10:33
  • Hum, correction on my previous comment: If you are not using the [R] flag, but your RewriteUrl returns a full url, the browser will be redirected too. – commonpike Apr 08 '16 at 12:11

3 Answers3

11

You need to capture the url request incoming into the server, like this:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/site/
RewriteRule ^(.*)$ /site/$1 [L,QSA]

The QSA is (eventually) to also append the query string to the rewritten url

guido
  • 18,864
  • 6
  • 70
  • 95
7

Same idea as @guido suggested, but a bit shortened using negative lookahead

RewriteEngine On
RewriteRule ^(?!site/)(.*)$ site/$1 [L]

Note: I am not using QSA flag as we are not adding additional parameters to the query string for the replacement URL. By default, Apache will pass the original query string along with the replacement URL.

http://www.example.com/index.php?one=1&two=2 

will be internally rewritten as

http://www.example.com/site/index.php?one=1&two=2

If you really want add a special parameter (ex: mode=rewrite) in the query string for every rewrite, then you can use the QSA Query String Append flag

RewriteEngine On
RewriteRule ^(?!site/)(.*)$ site/$1?mode=rewrite [L,QSA]

Then this will combine mode=rewrite with original query string

http://www.example.com/index.php?one=1&two=2 

to

http://www.example.com/site/index.php?mode=rewrite&one=1&two=2 
kums
  • 2,661
  • 2
  • 13
  • 16
  • In my case this did NOT work, the extra query parameters were NOT automatically sent, so i had to add the QSA just to get the normal GET parameters. I guess it depends on the server configuration (XAMPP in my case) – Larzan Jan 30 '17 at 14:57
1
RewriteEngine On

RewriteRule ^(.*)$ site/index.php?var=$1 [L]

With this rule, i'm passing all requests to site/index.php, so you could get the requested uri via $_GET['var'], and then you'll make the index.php serve the requested url behind the scene without the url changing in the user's browser. Ciao.

  • 1
    Does this solution require the requester agent to load the resource again at the new address (an External redirect), or does it directly return the resource at the new address (an Internal redirect)? So many redirection solutions on the Web don't include this information, which is important not only because it affects which address appears in the browser address bar and history, but also because some agents are not browsers and will not respond to redirection headers with a second request. – David Spector Sep 05 '18 at 11:30