1

I've been searching for 4 hours by now and I still can't get this to work. I have the following directories in my webroot:

- application
    - assets
    - css
    - config
    - protected
        - .htaccess
    - ...
    - .htaccess
- framework
    - [Yii framework inside]
- .htaccess

The .htaccess in my webroot should redirect/'rewrite' all requests for whatever xxx/xxx to http://www.example.com/application/ as long as the requested file or directory does not exist. This way requests for .css, .js and other files can still work.

In my config I made sure Yii expects SEO friendly URL's and I don't tend to use the index.php. So it now looks like this:

'urlManager'=>array(
        'urlFormat'=>'path',
        'showScriptName'=>false,
        'rules'=>array(
            '' => 'site/index',
            '<controller:\w+>/<id:\d+>'=>'<controller>/view',
            '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
            '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
        ),
    ),
    'request' => array(
        'baseUrl' => 'http://www.example.com',
    ),

The 'request' was added later on because Yii was generating links as example.com/application/site/login. With the request Yii generates example.com/site/login instead.

In the .htaccess in my webroot I tried about everything.

  • First I was able to 'remove' the subdir from the URL. The index page was shown.
  • I tried to add a rule so all none existing directories would be redirected to the same url.
  • My first rule broke, and 'application' was in the URL again, but no css styles were loaded.
  • At this moment I got the index page with css, but now everything brings me to the index page.

my .htaccess looks like this:

RewriteEngine on

RewriteCond $1 !^application/
# if a directory or a file exists, use it directly
RewriteCond %{DOCUMENT_ROOT}/application/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/application/$1 -d
RewriteRule ^(.*)$ application/$1 [L]

# otherwise forward it to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^.*$ application/index.php

Mod_rewrite is enabled (I know because some things worked before). I looked at examples from the Yii docs. I tried solutions from other questions on Stack Overflow like this one and many many others. Still no luck.

Could someone please help me out?


edit: With the .htaccess above a request to example.com ends at example.com/application .. I however would like to make the 'application' 'invisible' again (worked before, don't know why it broke)


I did change my .htaccess as follows:

RewriteEngine on

RewriteCond $1 !^application/
# if a directory or a file exists, use it directly
RewriteCond %{DOCUMENT_ROOT}/application/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/application/$1 -d
RewriteRule ^(.*)$ application/$1 [L]

# otherwise forward it to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ /application/
RewriteCond %{HTTP_HOST} ^(www.)?brainfeeder.be$
RewriteRule ^$ application/$1 [L,QSA]

But still a url like www.brainfeeder.be/site/login brings me to the default controller/action which is the site/index. I guess my conditions or rules are not exactly correct yet. Please see my small test application I set up to tackle this issue.

What happens: brainfeeder.be get rewritten to brainfeeder.be/application/ My Yii app is in there so it runs the 'bootstrap' index.php file and gets to the default controller/action, in this case site/index. Now when you click the 'login' button it should show you a login form. But it stays at the site/index view.


Ok, once again I updated my .htaccess a couple of times. Now I have the following situation:

  • www.example.com AND example.com are rewritten to www.example.com/application AND example.com/application.
  • (www.)?example.com/existingfolder just shows content of 'existingfolder'.
  • (www.)?example.com/var1/var2/../varn get redirected to (www.)?example.com/application/var1/var2/.../varn

Now the only thing I would like to happen is that the latter gets rewritten instead of redirected. So visitors don't know they are in the directory 'application'.

So (www.)?example.com/var1/var2/.../varn would bring the visitor directly to the correct page.

The contents of my .htaccess at the moment:

Options +FollowSymLinks
#IndexIgnore */*
RewriteEngine on

RewriteBase /

RewriteCond %{HTTP_HOST} ^(www.)?brainfeeder.be$
RewriteRule ^$ /application/ [L]

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^.*$ - [L]

# The directory or file does not exist
RewriteCond %{REQUEST_FILENAME} !-s [OR]
RewriteCond %{REQUEST_FILENAME} !-l [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /application/$1 [L,R]

The thing is, when losing the R flag in the last RewriteRule will bring me to the index.php file inside 'application' but it shows the home page instead of a login form when for example I go to example.com/site/login.

Which, I guess, the script does not see the vars. (if it did site/error would trigger) So it handles this as a request to example.com/application and not as example.com/application/var1/var2

I hope I did explain the problem better this time. Thanks for the great help 'till now.

Community
  • 1
  • 1
Brainfeeder
  • 2,604
  • 2
  • 19
  • 37

3 Answers3

3

Try to check these configuration directives if you just want to rewrite all the unexisting /$var1/$var2 to /application/:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ /application/

Now, if you want those unexisting files to redirect, rather than to rewrite them? Then just add a [R] flag at the end of the RewriteRule directive, just don't forget a single " " space before the flag.


Now, if you want to redirect /application to / and then rewrite /index.php to /application and to rewrite also the unexisting /$var1/$var2 to /application/$var1/$var2 then it's quite hard (and need some exact details) but you could still try these configuration directives:

RewriteEngine on

# rewrite index.php
RewriteRule ^index.php$ /application

# rewrite unexisting files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ /application/$1/$2

# try to remove this if it causes redirection loop
RewriteRule ^application/?$ / [R]

You can also try to use DirectoryIndex application/index.php at the very top of those directives to change the index of your site and remove the line RewriteRule ^index.php$ /application if it causes an error.

Actually, I can't understand your question.. You said:

The .htaccess in my webroot should redirect/'rewrite' all requests for whatever xxx/xxx to http://www.example.com/application/ as long as the requested file or directory does not exist. This way requests for .css, .js and other files can still work.

And now, you said to your comment:

So any link to brainfeeder.be/application/$var1/$var2 should be shown as brainfeeder.be/$var1/$var2

If you would also like to redirect existing /application/$var1/$var2 to /$var1/$var2 then please try to add these directives, and if it causes an error to your system, just remove it:

# the condition is important as mentioned above
RewriteCond %{REQUEST_URI} !\.css$
RewriteRule ^application/([^/]+)/([^/]+)/?$ /$1/$2 [R]

You can add another condition (as many as you like) at the top of the RewriteRule, just use your thinking if you're a programmer. You could add another condition like RewriteCond %{REQUEST_URI} !\.jpg$ if you doesn't want to redirect the file with an extension like .jpg or else that you want such:

RewriteCond %{REQUEST_URI} !\.css$
RewriteCond %{REQUEST_URI} !\.jpg$
RewriteCond %{REQUEST_URI} !\.png$
RewriteRule ^application/([^/]+)/([^/]+)/?$ /$1/$2 [R]

Please try to change the source of your .htaccess file with this code:

Options +FollowSymlinks
RewriteEngine on
RewriteBase /

RewriteCond %{HTTP_HOST} ^(www\.)?brainfeeder\.be$
RewriteRule ^/?$ /application/ [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /application/$1 [L]
  • This isn't working for me.. And please note that I want to rewrite (www.)?example.com/application to example.com as well. – Brainfeeder May 08 '13 at 10:55
  • @Brainfeeder Actually, I can't understand your question.. Are you online? Or could you make yourself online? – 5ervant - techintel.github.io May 09 '13 at 07:31
  • @Brainfeeder Please join in this room: http://chat.stackoverflow.com/rooms/28210/servant – 5ervant - techintel.github.io May 09 '13 at 09:08
  • It sais the room is frozen. – Brainfeeder May 09 '13 at 09:10
  • @Brainfeeder Yeah, it's already frozen.. What do you mean on your question? To rewrite *example.com/application* to *example.com/* and to rewrite unexisting *example.com/$var1/$var* to *example.com/*? – 5ervant - techintel.github.io May 09 '13 at 09:19
  • Well yes, but unexisting example.com/$var1/$var2 should be redirected to example.com/application in order to make my script recognize them. Only the application/ part should not be visible for visitors. I find this hard to explain :D look at [brainfeeder.be](http://www.brainfeeder.be) , it redirects OK as the index is in application, but if you click a link it wil still show the same page as $var1/$var2 seems to be ignored. – Brainfeeder May 09 '13 at 09:36
  • @Brainfeeder What do you mean about *"Only the application/ part should not be visible for visitors"*? – 5ervant - techintel.github.io May 09 '13 at 09:52
  • For the same reason I want brainfeeder.be to redirect to brainfeeder/application, the visitors should not know they are in a subdirectory. So any link to brainfeeder.be/application/$var1/$var2 should be shown as brainfeeder.be/$var1/$var2 .. OR how I would like it to be: a link to brainfeeder.be/$var1/$var2 should go to brainfeeder.be/application/$var1/$var2 without people knowing. :D – Brainfeeder May 09 '13 at 10:00
  • @Brainfeeder So you mean, you want to rewrite *brainfeeder.be/* to */application* and */$var1/$var2* to */aplication/$var1/$var2* ? And what is the index of your domain? Is it */index.html* or */index.php* or else? – 5ervant - techintel.github.io May 09 '13 at 10:18
  • 1
    Yes exactly, the index is a .php file, but in my application folder I have another .htaccess which takes care of the index.php file from Yii itself. The contents are exactly what the other answer was ;). – Brainfeeder May 09 '13 at 10:42
  • 1
    Any idea ? You would be my hero ! – Brainfeeder May 09 '13 at 13:39
  • Please check my updated question. Thanks for trying to fix this. – Brainfeeder May 09 '13 at 17:03
  • @Brainfeeder What do you mean? If you remove the `R` flag, the styles of the redirecting webpages are gone? – 5ervant - techintel.github.io May 09 '13 at 17:40
  • 1
    No the styles stay. I get to see the wrong page as in var1/var2 aren't seen by the index. I just get the default page which you should see when var1 and var2 aren't set – Brainfeeder May 09 '13 at 19:51
2

Not sure what your question is ...

But here is an .htaccess that should accomplish what you want:

RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php
Ivo Renkema
  • 2,188
  • 1
  • 29
  • 40
  • 1
    This only removes the index.php from the url. My Yii app is in a subdirectory in my webroot. I want to redirect visitors from the webroot to that subdirectory and the URL should remain www.example.com. Thus not www.example.com/subdirectory. The same was asked in [this](http://stackoverflow.com/questions/13636511/yii-removing-application-directory-name-from-url/16434375#16434375) question. – Brainfeeder May 08 '13 at 08:09
  • 1
    OK, now I understand what you want to do. I have to admit that my knowledge of Apache is too limited to really help you. – Ivo Renkema May 08 '13 at 11:45
0

You dont need to edit .htaccess. You just need to move the Yii entry script (index.php) and the default .htaccess up from the subdirectory to the webroot (so that they reside directly under public_html). After you move index.php and .htaccess to the root directory, all web requests will be routed directly to index.php under webroot (rather than to the subdirectory), thus eliminating the /subdirectory part of the url.

After moving the files, you will need to edit index.php to update the references to the yii.php file (under the Yii framework directory) as well as the Yii config file (main.php). Lastly, you will need to move the assets directory to directly the webroot, since by default, Yii expects the assets directory to be located in the same location as the entry script).

That should be all you need to do, but if you need more details I describe the approach more fully here:

http://muhammadatt.tumblr.com/post/83149364519/modifying-a-yii-application-to-run-from-a-subdirectory

  • Nice solution. However I wanted the subdirectory to be portable (in a very easy copy/paste way). That's why I liked the entry script to be in it's original place. By now I have 6 subdirectories running Yii from the same framework dir. – Brainfeeder Apr 22 '14 at 13:11