Zend Framework 1 tutorial Part 3: The ZF project htaccess file

If you have read the you should have created a public directory and if you installed XAMPP by using the following XAMPP tutorial, this directory will probably be in "C:\xampp\htdocs\myapp\public". Open the "public" folder of your app and create a new file called ".htacess" using your text editor or your IDE. If you can't see the htaccess file in the public folder after creating it, open the view "tab" in the Windows Explorer and enable "File name extensions and Hidden items" by clicking the checkbox next to it.

Adding an environment variable to our htaccess

The first thing we will add to our htaccess file is the environment variable. Our app will have an environment variable which will have three possible values, the first one is "development", the second one is "testing" and the third one is "production". "development" will be the environment type we will use while developing our application. "testing" is the environment variable value we will use while testing of our application and finally "production" is application environment we will use after we have deployed our application on the production server(s).

We will use those environment variables later in our app to check on under which environment the app is running and based on this we will enable or diable features of our app, like the cache, logging, ... You can add more environment types if you want and / or you can change their name to something else if you prefer.

Add the following lines to our htaccess file:


# this line sets the environment, set it to either "development", "testing" or "production"
SetEnv APPLICATION_ENVIRONMENT development

If you use another server, like nginx, that does not support htaccess files you could also set the environment variable in the project index.php or in the vhost file of your application.

Some server options

Now add those options to your htaccess, those will make your app environment more secure, what they exactly do is described in the comments:


# OPTIONS DIRECTIVE
# disallow directory content listing
Options -Indexes

# disallow server side includes, disallows also use of exec command
Options -Includes

# disallow execution of cgi files in this folder
Options -ExecCGI

# to allow rewrite rules, apache will only resolve symlinks where the user owns the target of the symlink
Options -FollowSymLinks +SymLinksIfOwnerMatch

The default Zend Framework rewrite rules

Now add the following rewrite rules to your htaccess file. First we enable the Apache rewrite engine. Then we use a 301 redirect to redirect users that use myapp.dev to access your website instead of www.myapp.dev. Finally the last lines are the default rewrite rules as recommended by the ZF team. They will redirect any url to the index.php in the public folder. The Zend Framework router will handle all the different URLs and automatically call the corresponding module, controller and action. More about this later.


# REWRITE RULES
# start mod_rewrite, this directive enables rewrite rules
RewriteEngine On
# Redirect domain.tld to www.domain.tld
RewriteCond %{HTTP_HOST} ^myapp\.dev$ [NC]
RewriteRule ^(.*)$ http://www.myapp.dev/$1 [R=301,L]
# zf rewrite rules, all requests except the ones that point to an existing file get redirected to index.php which will dispatch the request
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]

Adding PHP flags

The next part is optional. If you are the admin of your server and think it is correctly configured, then you might not need to set the following lines. You don't need to set those flags in your htaccess file if you have access to the php.ini. If you are on a shared server and don't have access to the php.ini you might want to change the php values using the htaccess file as showed below.

The first flag disables magicquotes. The second one disables register globals, both are deprecated and should not get used anymore.


# PHP FLAGS
# disable magic quotes, as of php 5.3.0 they are deprected
php_flag magic_quotes_gpc off
# disable register_globals, as of php 5.3.0 they are deprected
php_flag register_globals off

XML uses <? ?> as well as PHP. PHP calls them short open tags, so we deactivate the short open tag support to avoid problems with XML strings, it's anyway recommended that you always use the full php opening tag <?php anyway.

Then we also disable sessions auto start as we will handle the start and stop of session ourself when needed and don't need this option for our app session auto start.


# enabled by default
php_flag short_open_tag off
# disable auto start of sessions
php_value session.auto_start 0

We disable url fopen, because attackers of your website might want to use this feature to load remote scripts onto your server. If you need that feature yourself comment this line out. Then we enable another feature, gzip compression is used to compress static files that get send to the client.


# disallow url fopen
php_flag allow_url_fopen off
# allow gzip compression
php_flag zlib.output_compression on

These php flags disable some php functions that we probably will never need but which hackers might want to use to hack your website, so we disable them. If you want to use one of them, comment the corresponding line out or remove the line.


# disable some php functions we wont use and dont want to be available
php_flag disable_functions show_source
php_flag disable_functions system
php_flag disable_functions shell_exec
php_flag disable_functions passthru
php_flag disable_functions exec
php_flag disable_functions phpinfo
php_flag disable_functions popen
php_flag disable_functions proc_open

To improve the loading time of your website it is recommeded to gzip files before sending them to the client, the next lines will do that for you:


# deflate output filter that allows output from your server to be compressed before being sent to the client
<FilesMatch ".(js|css)$">
SetOutputFilter DEFLATE
</FilesMatch>

Those are the last lines I recommend adding, they will tall Apache to use Etags to tell the browser to cache static files up to 5 days:


# cache expiraten of static files like images, js and css files will be set to 5 days
# set etags so that the browser knows which file is new
<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=290304000, public"
FileETag MTime Size
</FilesMatch>

That's it, your htaccess file is ready, don't forget to save it ;).

More information about apache .htaccess files can be found here: http://httpd.apache.org/docs/2.0/howto/htaccess.html

More information about the Apache 2.2 options directive: http://httpd.apache.org/docs/2.2/mod/core.html#options

More information about the rewrite rules used for Zend Framework applications: http://framework.zend.com/wiki/display/ZFDEV/Configuring+Your+URL+Rewriter

More information about php flags: http://php.net/manual/en/ini.core.php

More information about the Deflate Output Filter: http://httpd.apache.org/docs/2.0/mod/mod_deflate.html

More information about the ETag (Entity Tag): http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19