When developing a large-scale PHP application, there is an inextricable requirement for multiple servers or development environments throughout the development process.
Of course, ultimately, your completed application, be it a public Web site or a closed intranet application, will reside on a server somewhere. This server may be in a dedicated data center or simply in the server cupboard of the client company.
This server is, however, the production server. It may not even have been purchased when you start the project. As a result, a series of interim environments are required to provide the chronological stepping stones for the deployment of your project.
You will need to equip your development team with a local development environment in which to develop.
In this example, we assume that your project is called Widgets. Your local development server will probably sit on your internal network only, with an IP address of 192.168.1.1 or similar, and not be exposed to the outside world. You may also have devised an internal domain name maybe mydevelopmentco.local which resolves using only your own internal DNS servers.
You may then establish a virtual server in Apache or your Web server of choice:
The corresponding entry in Apache's httpd.conf would be:
<VirtualHost 192.168.1.1:80> ServerName dev.widgets.mydevelopmentco.local ServerAdmin email@example.com CustomLog /home/widgets/logfile_wid common ErrorLog /home/widgets/errlog_wid DocumentRoot /home/widgets/public_html/dev/php </VirtualHost>
Obviously, you would amend the IP address, server name, e-mail addresses, and paths to match, and configuration syntax in other Web servers would of course be subtly different.
You would, obviously, need to expose the home directory of the user widgets to all of your development team, such that they may modify the code. In a typical setup, they may be using Windows workstations to modify code; in such a case, the use of Samba (www.samba.org) is highly recommended to create a network drive from which they can access the source base.
Modifications that your team then makes to the source base will be visible at the development URL only http://dev.widgets.mydevelopmentco.local and not on the live site.
If you are using any form of version control methodology as described in Appendix A, you need to provide virtual server instances for each of your developers, too such as http://johndoe.dev.widgets.mydevelopmentco.local. More detail on this setup is provided in Appendix A. In such a setup, the master development server alluded to previously still exists but is a reflection of the source base as committed to the version control repository, rather than of any in-progress development.
It can be time-consuming in larger development studio environments to have to create DNS entries for every new project and, if using version control, every new developer, too. If you are using just one physical server for all your projects, you can simplify this process by using a Wildcard DNS setup. This means that *.mydevel- opmentco.local will automatically resolve to 192.168.1.1. You can find information on how to do this on the Web. Just search for "Wildcard DNS.''
As a development outfit, you will want a production server of your own a place for you and your team to host your own ratified, finalized code prior to dispatch to the client.
If you're using version control, this will be a reflection of your repository, but not necessarily of the very latest versions in all cases. Rather, it will be the latest versions of each file that have been approved for submission to the client. In practice, this will represent the versions of each file that have been tagged as release. You can find more information on tagging in Appendix A.
The studio staging environment is of most use to project managers wishing to assess the true progress of a project, and for QA and testing where modifications to the live database cannot be risked.
In the previous example, our studio staging environment might be named:
The corresponding Apache entry may read as follows:
<VirtualHost 192.168.1.1:80> ServerName dev.widgets.mydevelopmentco.local ServerAdmin firstname.lastname@example.org CustomLog /home/widgets/logfile_wid-staging common ErrorLog /home/widgets/errlog_wid-staging DocumentRoot /home/widgets/public_html/staging/php </VirtualHost>
The live staging environment provides a test bed for you to demonstrate new functionality to your client prior to release onto the live production environment.
The staging environment is typically hosted on the same server as the production environment, but with a subtly different URL. For example, if your live site was called http://www.widgets.com, you might use http://staging.widgets.com for your live staging environment.
A typical Apache configuration might read as follows:
<VirtualHost 192.168.2.1:80> ServerName staging.widgets.com ServerAdmin email@example.com CustomLog /home/widgets/logfile_wid-staging common ErrorLog /home/widgets/errlog_wid-staging DocumentRoot /home/widgets/public_html/staging/php </VirtualHost>
Note the different IP address indeed, a different subnet compared with your development server. It's worth using different private address ranges for each cluster of servers for which you are responsible. Because your live staging environment will likely reside in a data center and not on your local network, a second subnet has been introduced: 192.168.2.x instead of 192.168.1.x. Keeping subnets different will allow you to configure VPN (Virtual Private Network) access to your remote data center more easily should you ever wish to do so. It's also a lot less confusing.
If your live production environment uses multiple servers in a load-balanced configuration, you're wise to run your staging environment off a single server. After all, your staging environment is unlikely to attract the kinds of loads that warrant the use of multiple servers.
It may be prudent to protect your live staging environment with a username and password because it is, strictly speaking, publicly accessible. You should avoid using an .htaccess file to accomplish this, however, because that file risks being replicated onto your production environment during deployment, which would expose your live environment to that same password protection.
Instead, you can add this layer of security directly into your Apache configuration file:
<VirtualHost 192.168.2.1:80> ServerName staging.widgets.com ServerAdmin firstname.lastname@example.org CustomLog /home/widgets/logfile_wid-staging common ErrorLog /home/widgets/errlog_wid-staging DocumentRoot /home/widgets/public_html/staging/php <Directory /home/widgets/public_html/staging/php> AuthType Basic AuthName Staging AuthUserFile /home/widgets/.htpasswd Satisfy All Require valid-user </Directory> </VirtualHost>
The .htpasswd file is created in the normal manner; that is, using /usr/local/apache/bin/htpasswd.
Finally, your live production environment provides the environment that the public sees. This may not be the general public if this is a closed system, but it is nonetheless the place for fully tested, fully approved, ratified code.
A typical Apache configuration might read as follows:
<VirtualHost 192.168.2.1:80> ServerName www.widgets.com ServerAdmin email@example.com CustomLog /home/widgets/logfile_wid-live common ErrorLog /home/widgets/errlog_wid-live DocumentRoot /home/widgets/public_html/live/php </VirtualHost>
Assuming that your application is database driven, you will need to make a conscious decision about what instance of the database (that is, which physical server and which database on that server) should be used for each of your environments.
This is particularly pertinent considering that certain evolutions of code may require modifications to database schema that, if made against a production database still being driven by an older release of code, would surely cause errors.
With this in mind, consider the following strategy:
Individual development environments if used, should employ a locally hosted database, specific to that individual; for example, John Doe will use a database called widgets-johndoe.
The master development environment should employ a locally hosted database (perhaps simply named widgets-dev), not specific to any individual developer but reflecting the latest database schema required to support the very latest versions from your version control platform.
The studio staging environment should employ a locally hosted database (perhaps simply named widgets-stg), not specific to any individual developer but reflecting the latest database schema required to support the latest release-tagged versions from your version control platform.
The live production environment should, naturally, use the live database server and the live database.
The live staging environment should also use the live database so that when it's being used by the client for testing and approval purposes, it provides an accurate reflection of how the live environment will behave once the changes are deployed.
Of course, with at least four databases in existence at any one time, keeping track of necessary changes to the database schema itself can be tricky.
Version control software is of little use here. Yes, it is possible to maintain a dump of the database structure in your repository, but simply retrieving this dump will not physically update the database schema when it is downloaded. Simply dropping and recreating the database is an option, but this will lose any test data stored therein. It is also difficult to use such an SQL "dump'' file to determine differences in database schema when you're working on larger projects.
The best approach, therefore, is one of good communications. Version control can play an important part here. Creating a folder called db-changes in your repository and instructing your developers to add text files containing a series of ALTER statements whenever they make changes to the database schema means that any developer performing "get latest versions'' will also receive a series of changes to make to his or her own database.
Such files can, also, be tagged as release so that those responsible for maintaining the master development and studio staging environments can ensure that both databases are kept up-to-date to the appropriate degree.
Telling your application which database to use can result in awkward switch statements or, worse, hard-coded values that need changing by hand. There is another way, however. You doubtless have a file called constants.phpm or similar that dictates database IP address, database name, username, password, and so forth. By adapting this to consult the $_SERVER["HTTP_HOST"] property, the database IP, name, user-name, and password can be conditionally and dynamically determined and the correct database selected automatically, depending on the virtual server being used. Everybody can, therefore, share the same constants file.