Sometimes you need to move your code off of the computer you wrote it for and onto some other machine. A buddy wants a copy of your random D&D dungeon generator. A co-worker needs a copy of the billing software you’ve been working on. A client wants you to move their inventory software to a new system.
And when you get a job like this it quickly becomes apparent that some programs are easier to move than others. A simple Java application can be tossed onto just about any machine and stand a good chance of automagically working while a complex piece of legacy code might be almost impossible to move due to dependency on obsolete libraries or bizarre hardware requirements*.
Now unfortunately for us web developers, online applications tend to be some of the harder pieces of software to move from one computer to another. In general it’s not enough to just have a copy of the code moved to the new machine; you also need a copy of the right database and server along with the proper database table definitions and server config instructions.
And that’s just the starting point. The older and more complex your web app is the higher the odds are that it has developed dependencies of certain URLs, IP addresses, third party data feeds, server libraries and so on. At that point you’re no longer trying to move an application, you’re trying to relocate an entire digital ecosystem.
But I’m Never Ever Going To Move My Web App To A Different Computer
Now at this point you might be thinking to yourself “But Scott, web apps don’t need to move. You just install them on your server and let other people visit them through the Internet. That’s the whole point.”
And for the most part that’s true. If your web app runs properly on its current server it doesn’t really matter how hard or easy it would be to get a second copy of your web app running on a different server with a different URL.
Until one day you find out your website is so popular that it’s starting to slow down and you need to create a second copy and load balance between the two.
Or maybe someone offers to pay you a bunch of money to build a copy of your web app for their business.
Or maybe you find out you need a bunch of risky new features and you want to create a test server to run your changes on before you update the main server.
Or maybe you finally get enough funding to hire a second developer and now he needs to know how to set up a local copy of your online web app so he can start experimenting without taking down half your live database.
Take your pick. There are plenty of reasons that a complex website that you thought would always run on just one machine with just one URL might suddenly need to be split across multiple computers with various different access methods.
Oh No! How Do I Prevent This From Ruining My Web App?
Fortunately, there are ways to make your online applications easier to move and copy.
Probably the most important tip is: Avoid hard coding resource locations.
Hard coding the IP address of your database straight into your code will result in all sorts of headaches when some new developer comes along and wants to connect to localhost or a test database instead. Similarly hard coding the location of libraries (ex: /home/bob/businessapp/library/coolstuff.php) can lead to extreme frustration if your app ever ends up installed in a different location or even on a different operating system. You’ll wind up being forced to hunt down and replace dozens or hundreds of file references with new locations that match the new machine.
The fix for this is to store environment specific data like code paths and database connection credentials in some sort of variable instead.
//BAD! This will make it really hard to run this code on a different machine or OS include('/home/bob/businessapp/library/coolstuff.php'); include('/home/bob/businessapp/library/importantstuff.php'); //BETTER! Now we can adapt this code to new machines by changing just one variable $libraryPath = '/home/bob/businessapp/library/'; include($libraryPath.'coolstuff.php'); include($libraryPath.'importantstuff.php');
But where should you declare these environment specific variables?
Your first instinct might be to just store them in the same file where they are used. Put the database variables at the top of your database connection script or your library path at the top of the file that loads up all the support code for your framework.
But mixing up environment variables and code can be dangerous.
For instance, imagine you send your buddy a copy of your web app and teach him how to customize the connection information in the database file “database.php”. Then a few months later you find a bug in that code and have to send him an updated copy. He deletes his broken “database.php”, loads the new one and suddenly nothing works because deleting the old “database.php” file also deleted the customi connection information that pointed to his database.
But what if you instead had two files: a “database_connect.php” file that has the actual database logic and a “database_config.php” file that just holds a few variables for database location and authentication. You give your friend a copy of both and show him how to update “database_config.php”. A few months later you find an error in the logic of “database_connect.php” and send him an update. This time everything works perfectly because replacing the broken “database_connect.php” file had no impact on the customized variables your friend had entered into “database_config.php”.
This is the basic idea behind config files. Sometimes they’re text files holding values for the code to read. Other times they are actual code files filled with static variables. But no matter how they are written the goal is the same: to create a file that will never be overwritten by bug fixes or feature updates; a safe place for keeping track of machine and user specific information.
Keep that in mind when designing your next major web app and you should hopefully find yourself in a situation where copying or duplicating your program is as easy as copying some code and updating a few config files. And doesn’t that sound like a lot more fun than trying to manually find and replace dozens of hard coded references that keep trying to overwrite each other every time you install an update?
* Example: Sometimes software, especially in embedded systems, keeps track of time by counting processor cycles. As you can imagine a program that thinks one second is equal to one million processor cycles will start acting really weird if you give it a processor that runs several times faster than that.