Virtually every PHP application structures all its files under one directory, which is then dumped into the web-accessible root. This is the "plug and play" approach. All the "developer" needs to do is drop the bundle and its hundreds of files (Moodle or WordPress anyone?) into a folder, and off they go.
Any program, regardless of programming language (PHP, Python, Java) or communication channel (HTML/XML, tk, Swing) is composed not just of the primary files, but also of a number of auxiliary resources: images, CSS, and even other secondary class definitions.
In the case of a web application, these secondary helper files should be kept away from the web-accessible root. Indeed, the basic tenet ought to be:
Only files that need to be read by a client (browser) should be made directly available through the web server.
If done correctly, this means the only files that should be "dropped" into the server's DocumentRoot are:
- CSS files,
- image files,
- HTML files,
and the few PHP files (like index.php) that will actually be served. If you don't expect a file to return when addressed directly, then don't make it available in the first place.
Hide your underwear#
Of all the files to be hidden this way, the configuration files—and there should really be only one—are the most important. These are the files that actually contain sensitive information like database passwords and salts; and every precaution ought to be taken to make sure their contents are not accidentally divulged.
Many projects have been compromised by an accidental web-server misconfiguration which exposed PHP files as plain text. And while your code should be strong enough that it may freely be distributed as open source, your configuration files never should.
Along the same lines, every application comes with necessary files like README, COPYRIGHT, et. al. Once delivered, these files are of no concern to the user of your application. A sure way of telling if any real attention has been given to the security of a web application is to see how much dirty laundry lays exposed.
Cleaner code is better code#
Keeping your applications tidy is sage advice. In Java, namespaces—which translate to directories on the disk—help preserve clean, well-structured code. The same should be done in PHP applications. Here's the basic file structure we recommend for a project:
- (Root) MyProject/
- other administrative files
- other helper PHP files
The entire project is stored under one directory, here called MyProject. The web-accessible files are stored under a subdirectory called www. In Apache-speak, this directory represents the DocumentRoot for the VirtualHost. For completeness, we have included non-PHP files in this directory, which we group concisely under the inc directory (inc = include).
Meanwhile, all the PHP auxiliary files (class definitions, configuration files) are placed in a different directory we call lib. The point is that the files in this directory will never be directly served by the web server.
This architecture has several side benefits, as well. Within the project's root directory are the administrative files, right where they should be.
Of course, any project worth its salt is under tight version control. If you're using Mercurial or git, then all of the version control files will be stored under MyProject/.hg or MyProject/.git, respectively. The lesson is that these files, too, are outside the web-accessible folder. This kind of control is not possible with the more commonplace architecture.
Organizing your code this way is the first step towards quality, secure, web applications. Of course, there are other important rules to follow, and technical challenges to overcome.
In other articles, we discuss how to setup the server (and Apache) to use this project architecture. We will expand on the basic file structure above, in the process showcasing the many benefits of proper file layouts.