Update: Symfony 2.2 now includes .htaccess rules that eliminate the app_dev.php duplication issue.

Non-WWW Vs. WWW

An SEO best practice that I've adopted is to redirect the www domain alias to the non-www version.

While this old discussion forum thread may not be the most up-to-date (partially because of Google’s Webmaster Tools aforementioned preference), it is to the point. Though you may want all foo.com requests to redirect to www.foo.com, I prefer the contrary, since that shortens the domain name.

Deny App_dev.php

By default Symfony provides a front controller app_dev.php to give access to their dev environment along with the Symfony debug bar. I bypassed their following security measure that denies access to this front controller when not being accessed from localhost because I also have a hosted version of my Development environment.

// within app_dev.php
//if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
//    '127.0.0.1',
//    '::1',
//))) {
//    header('HTTP/1.0 403 Forbidden');
//    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');

To compensate for allowing full access to the dev environment on the production side, I used the %{DOCUMENT_ROOT} variable to detect the production by way of the web root location. Why do that? Well, by detecting the web root, I have the flexibility to upload my working copy to other hosted web roots that represent the Development and Integration environments without having to reconfigure anything. (By the way, here is a very useful .htaccess cheat sheet.)

Deny Direct App.php

Since app.php takes any and all requests that aren’t real files—namely the routes you create like /foo/bar—there is no need for /app.php/foo/bar to work as well on the production end. In fact, if it were to work as well on the production end, the result would be non-malicious duplicate content. (See this article for more info on duplicate content/ why you should avoid it.) This approach, in the end, is much more SEO-friendly.

The complete .htaccess file looks like this.

ErrorDocument 404 /404.html  
<IfModule mod_rewrite.c>  
    RewriteEngine On

    # Non-www Vs. www
    #in production environment, redirect www.foo.com -> foo.com
    RewriteCond %{HTTP_HOST} ^www
    RewriteCond %{DOCUMENT_ROOT} /var/www/html/www.foo.com/Symfony/web
    RewriteRule (.*) http://foo.com/$1 [R=301,L]

    # Deny app_dev.php
    #in production environment, no app_dev.php
    RewriteCond %{REQUEST_FILENAME} app_dev.php
    RewriteCond %{DOCUMENT_ROOT} /var/www/html/www.foo.com/Symfony/web
    RewriteRule (.*) - [R=404,L]

    # Deny direct app.php
    #in production environment, no app.php directly
    RewriteCond %{DOCUMENT_ROOT} /var/www/html/www.foo.com/Symfony/web
    RewriteCond %{REQUEST_URI} ^/app\.php/.*
    RewriteRule (.*) - [R=404,L]

    #pass everything else through app.php if not a physical file
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>