14

I have the following .htaccess file in my web directory for my Symfony2 installation:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*) app.php [QSA,L]
</IfModule>

However, when I try something basic such as:

(whatever)/web/app.php/place

it doesn't removing the app.php from the URL. I'm new to Apache and I'm not sure what's going on here, can anyone shed some light? Thanks in advance!

EDIT: Due to the structure of the web app I am working with I cannot move app.php or app_dev.php outside of the web folder nor can I modify the server configuration of Apache in anyway, thus I am looking for an alternative solution to this problem.

celestialorb
  • 1,901
  • 7
  • 29
  • 50

7 Answers7

25

You must enable the rewrite module in Apache, as the "IfModule mod_rewrite.c" states.

To do so:

  1. Run command-line command "a2enmod rewrite".
  2. Change all "AllowOverride None" lines to "AllowOverride All".

See http://www.lavluda.com/2007/07/15/how-to-enable-mod_rewrite-in-apache22-debian/.

Pat Zabawa
  • 730
  • 1
  • 11
  • 23
21

That rewrite rule is not meant to remove app.php from the URL. It's purpose is to use app.php for every request, if a request URL doesn't correspond to a real file. Since app.php is a real file, it will be used to serve a request.

If you want get rid of web/app.php part, first create a virtual host pointing to the web folder:

<VirtualHost *:80>
    ServerName whatever
    DocumentRoot /path/to/project/web
</VirtualHost>

This will remove the web part.

Then, to remove the app.php part, add this to the beginning of the web/.htaccess file:

RedirectMatch permanent ^/app\.php/(.*) /$1
Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133
  • There's no need to "remove" the app.php part. You're correct about making the DocumentRoot into the `web` directory as the symfony docs says to do so, but travelling to any route will automatically route through app.php. So for instance if you go to `www.acme.com/blog/article/1` the default .htaccess re-write will route to `www.acme.com/app.php/blog/article/1` but there is no need to navigate directly to the path with app.php in it. Sorry if I've miss-understood your post but some clarification might be needed: By default there is no requirement for a user to navigate through app.php. – Kasheen Dec 08 '11 at 17:45
  • 3
    You are right — `app.php` will be used anyway because of the rewrite rule in the `.htaccess` file. What my `RedirectMatch` directive does is not to let users go to `app.php` **explicitly**. If a user somehow gets to `www.acme.com/app.php/home` she will be redirected to `www.acme.com/home` — that's all there is to it. – Elnur Abdurrakhimov Dec 08 '11 at 19:27
  • Do we really need a VirtualHost even in case of a user maintaining single hostname/domain? – Mayank Jul 25 '12 at 07:39
  • Is this possible without Virtual hosts? – Tool Nov 21 '12 at 20:37
  • How it can be achieved using only .htaccess when there is shared hosting being used and you can not make changes in .ini file. – Neeraj Aug 09 '13 at 07:41
4

I had this problem today and the fix was to append a /$1 at the end of the url rewrite rule.

My .htaccess looks like this:

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php/$1 [QSA,L]
</IfModule>

And the virtual host is defines as this:

<VirtualHost *:80>
   DocumentRoot /var/www/html/symfony_site/web
   DirectoryIndex app.php
   <Directory /var/www/html/symfony_site/web >
       AllowOverride All
       Allow from All
   </Directory>
</VirtualHost>
Marin
  • 1,268
  • 12
  • 7
4

I just got the same issue and I fixed it like this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /web/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
gimpe
  • 1,057
  • 10
  • 12
0

When you write RewriteCond %{REQUEST_FILENAME} !-f you say "Don't change real files... they should still be reachable." If you remove that, it should work.

The reason for it allowing that is some frameworks let you use http://site.tld/script.php/abc=123&def=456 style of links.

If you want it to allow filenames except app.php, you could add that as another RewriteCond.

Brigand
  • 84,529
  • 20
  • 165
  • 173
0

We've been struggling with that as well. There are two solutions:

  1. set document root of your virtual host to point directly to the /web/ subfolder (as per Symfony2 guidance)
  2. move app.php and app_dev.php outside of the /web/ subfolder, then update .htaccess and include paths in both files accordingly (i.e. remove web/ to correct all paths after you've manually moved the files one folder above)

(Note: cannot provide examples from vanilla installation of S2, since symfony.com seems to be down at the moment.)

MicE
  • 5,038
  • 2
  • 29
  • 26
  • Why the downvote? This is a working solution that solves OP's problem - please explain, thank you. – MicE Dec 08 '11 at 23:30
  • Unfortunately I cannot set the document root of a VirtualHost to point directly to the web subfolder due to my restrictions so this method will not work for my case. :( – celestialorb Dec 09 '11 at 20:47
  • @celestialorb: Yes, I assumed that would be the case - that's why I provided the second option above. In our case, we had to host an S2-powered site in a subdirectory of an existing site, so the first option was not available to us. And rewriting the URL via .htaccess caused several problems with path autodetection in S2 (since we were 2 levels deep from document root). The second option from the answer above solved it, and it will work for your case as well. – MicE Dec 10 '11 at 12:12
  • 1
    @MicE Can you please also explain how would .htaccess look like after moving app.php and app_dev.php? Also, would there need to create another .htaccess at root? – Neeraj Aug 09 '13 at 07:39
0

I managed to remove web/app.php part on my shared server.

  1. First I moved app.php out of the web directory one step above thus my app.php on the root directory. Then I placed a .htaccess on the root directory
RewriteEngine on

RewriteBase /

RewriteRule ^css/(.*) web/css/$1

RewriteRule ^images/(.*) web/images/$1

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]

I used RewriteCond on css and images as they still lie inside /web/ directory so all request to css and images will be routed to web/css and web/images directories respectively.

It worked well for me.

M Khalid Junaid
  • 63,861
  • 10
  • 90
  • 118
Neeraj
  • 607
  • 5
  • 5
  • 4
    Sorry for being blunt, but this is ridiculous. web/ folder is there for a reason. You should NEVER leave PHP file visible to the public. Point the virtualhost to the web/ folder, and adjust rewrite conditions to remove the app.php, or use index.php that include app.php. That way, you do NOT touch provided framework code.... and do not expose your code to be potentially read publicly # Imagine you had this available. AddType application/x-httpd-php-source php – renoirb Mar 29 '12 at 19:10
  • @neeraj: I followed the second option as you suggested but i get a blank page when i hit my URL http://localhost/symfony/ i also don't want to use VirtualHost... Please suggest. – Neeraj Aug 09 '13 at 09:18