Before using a test server, my web programming experience was really slower. In fact, every time I had to modify something or try a piece of code, I had to upload it first to my remote server. If the Internet connection had a fluctuation, I could not continue working at all. This also meant I had to first set up a test website if I didn’t work on the live address. One day I had the curiosity of checking out one of these LAMP distributions (Linux, Apache, MySQL and PHP), just with the Linux variable taken out. They call them a LAMP package for Windows. It contains a preconfigured Apache 2 server with PHP 4 and 5, a switcher between the two, MySQL 5 (you even got a phpMyAdmin script already set up) and a mail server called Mercury32 that enables you to send and receive mails from your own scripts, check out newsletters and so on.

I installed the package only once, because after that, I used the same setup over the next Windows installations, just copying the old directory. The package has a cool script that sets up the MySQL and Apache servers as system services and makes them start up at the computer boot (simply remember that this script needs to run with Administrator priviledges under Windows Vista).
As I didn’t want to touch the preconfigured website (a nice panel that shows the working services, has examples of the various functionalities and a phpMyAdmin script) I ended setting up a virtualhost for each website I was working. Apache (the web server) has a function that makes you share multiple sites on the same machine and using the same web server. Every decent webserver today has these functions, Apache calls these sites virtualhosts.
In a production environment, you would set up each virtualhost with his domain name (I did so for my test server initially), but this meant each time you had to test the site, you had to be connected to Internet or set up a name server, because otherwise the system couldn’t find the virtualhost. I assigned a different port for each server, starting from 81 (80 is the standard HTTP port) and going on. However, I suggest always use a port higher than 1024 for custom services like these, because the web server could collide with other services or use reserved ports.
Configuring these virtualhosts means creating a new folder that contains the site files (a new site root) and modify two configuration files (don’t worry, they are explained in plain english, it’s very simple), in the main file we tell Apache to start listening to another port, in the other file we add the virtualhost directive (some lines you always end up copy and paste and maybe customizing later).
As for simplification purposes I imagine you already downloaded and installed the LAMP distro, I personally use XAMPP (my installation folder is D:\xampp, because my OS stays in the C: drive and this way I don’t have to move anything when I reinstall, adjust as you need, but I really recommend for a x:\XAMPP path).
Open D:\xampp\apache\conf\httpd.conf with a text editor, after the line

Listen 80

that tells the server to listen to port 80, add this

Listen 81

then scroll at the bottom, and before the last block

#
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
#
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>

add this two lines

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

this tells the server to include a new text file in the configuration, where we’ll put everything related to virtualhosts.
Next time we’ll need to add a new virtualhost, in the main httpd.conf file we will only need to add a Listen 82, Listen 83, Listen 84 [...].
Now save, go in D:\xampp\apache\conf\extra and create this httpd-vhosts.conf file.
Add these lines

# Virtualhost domainname.com - port 81
<VirtualHost *:81>
DocumentRoot D:\xampp\htdocs\virtualhosts\domainname.com
ServerName localhost:81
</VirtualHost>

then save and exit. Ah, remember that domainname.com should be replaced with your site domain’s, for example ebay.com or yahoo.com.
We’re almost done, you just need to go to D:\xampp\htdocs, create here a virtualhosts folder (here well’put the document root of each of our virtualhosts) and in the virtualhosts folder put a domainname.com folder (replace with your site domain’s).
If you want to be sure everything works, put a file called index.htm in the domainname.com folder and add this line in it

If you can read this, the domainname.com - port 81 virtualhost works correctly.

then save and exit.
Now stop and restart Apache (Administration Tools/Show local services in the Control Panel, find Apache2, click Stop, then click Start) and if everything is right, you will see the message wrote in the index.htm file by going with the browser to the url

http://localhost:81

Congratulations. And now? There are some optional steps you can make

  • If you got a dynamic IP, you will need to set up a dynamic DNS service to bind it to a domain name. I use DynDNS, it’s the most famous I think. You’ll need to open a free account, add a dynamic DNS service. If your router natively supports dynamic DNS refreshes (has a dyndns client in the firmware) log on to the router, find the function, insert your dyndns domain, username and password, save and restart. If you’re not sure, you’ll need a dyndns refresh client you can find here.
  • If you’re behind a firewall, you will need to open the ports you are using.
  • If you are using a router, you will need to use the port forwarding feature of the NAT to explain your router how to serve requests from outside.
  • If you want to use MySQL, the default password is blank, that means everyone from outside will be able to read your test data. Not a big problem, but better change it using the phpMyAdmin script (located at http://localhost/phpmyadmin). While you’re using the phpmyadmin script, add a database to each domain in the form domainname_com, so you can access it.
  • The mail server has not a startup script yet, you will need to call it when you will need it. I created a shortcut to D:\xampp\MercuryMail\mercury.exe in my Quick Launch bar. When started, an icon will appear on the tray, double click it to bring the server control panel. I suggest you add a test POP3 account by clicking the Configuration menu, Manage local users, username test and password test. You will be able to add this mailbox to your email software.

Now your server is visible from outside, you got a database for each domain, you know how to add virtualhosts. What to add to the list? Really simple, you should make your PHP scripts server-aware!
This means having the remote, live settings and the test server settings on the same script, and having the script "detect" if it’s running on a test server or on the live server.
You can do it this way:

$testserver = $_SERVER["SERVER_NAME"]=="localhost";
now if the $testserver variable is true, you use some settings, send email to the test account and so on.
Example:
if ($testserver) {
$dbuser = "root";
$dbpass = "";
$dbhost = "localhost";
$dbname = "domainname_com";
} else {
// your hosting provider’s data
}

and if you use mail functions

if ($testserver) {
// mail to the ‘test’ account
} else {
// mail to the real user
}

To syncronize your test site with your live site, simply copy the virtualhost document root in a D:\sites folder (always do that! you will know exactly the state of the live server and it will provide a backup, do not load from the virtualhost document root!).
To load the MySQL database, export it to SQL and import it on the live server with the phpMyAdmin script of the hosting provider.