A free and open-source book on ZF3 for beginners

2.7. Hypertext Access File (.htaccess)

We've mentioned the APP_DIR/public/.htaccess file when talking about typical directory structure. Now let's try to understand the role of this file.

The .htaccess (hypertext access) file is actually an Apache web server's configuration file allowing to override some web server's global configuration. The .htaccess file is a directory-level configuration, which means it affects only its owning directory and all sub-directories.

The content of .htaccess file is presented below:

RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [L]
# The following rewrites all other queries to index.php. The 
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting or installed the project in a subdirectory,
# the base path will be prepended to allow proper resolution of
# the index.php file; it will work in non-aliased environments
# as well, providing a safe, one-size fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]

Line 1 tells Apache web server to enable URL rewrite engine (mod_rewrite). The rewrite engine modifies the incoming URL requests, based on regular expression rules. This allows you to map arbitrary URLs onto your internal URL structure in any way you like.

Lines 4 - 7 define rewrite rules that tell the web server that if the client (web browser) requests a file that exists in the document root directory, than to return the contents of that file as HTTP response. Because we have our public directory inside of the virtual host's document root, we allow site users to see all files inside of the public directory, including index.php, CSS files, JavaScript files and image files.

Lines 14 - 16 define rewrite rules that tell Apache what to do if the site user requests a file which does not exist in document root. In such a case, the user should be redirected to index.php.

Table 2.1 contains several URL rewrite examples. The first and second URLs point to existing files, so mod_rewrite returns the requested file paths. The URL in the third example points to a non-existent file htpasswd (which may be a symptom of a hacker attack), and based on our rewrite rules, the engine returns index.php file.

Table 2.1. URL rewrite examples
Requested URL Rewritten URL
http://localhost/index.php File exists; return the local file APP_DIR/public/index.php
http://localhost/css/bootstrap.css File exists; return the local file APP_DIR/public/css/bootstrap.css
http://localhost/htpasswd File does not exist; return APP_DIR/public/index.php instead.