How I set up my local PHP development environment on Mac OSX Yosemite in three easy steps

When I first started writing this post, I considered giving it a title such as “How to set up local PHP development with dynamically configured mass virtual hosting on Apache 2.4”, “Quick and easy prototyping using Liip PHP, Dnsmasq or Proxy Auto Configuration” or even “The Ultimate Guide to Rapid Development on OSX 10.10”. I did not.

In my daily job as a Development Manager, I don’t get to code very much, but when I do, I want to have a setup that allows me to quickly create development projects and prototypes in the ~/Sites folder and have them show up as vhosts automagically, without having to edit any configuration file(s).

I also want to make sure my pseudo-toplevel domain .dev resolves to localhost and any domains/subdomains i choose to create lead into the relevant web root folder.


If you want to follow this step-by-step rendition, you are required to have the following:

  • A Mac, with OSX 10.10+ (Yosemite) installed
  • A working install of Apache 2.4 (comes preinstalled with OSX Yosemite)
  • Homebrew installed
  • A text editor and some fingers

Step 1 – installing (my preferred version of) PHP

From our good friends at Liip comes several binary PHP packages perfectly suited for development, each representing different versions of PHP, from 5.3 to the current stable version (at the time of writing version 5.6.4). I am going to install the latest version, so I open my terminal shell and execute:

This install doesn’t overwrite the PHP installed by Apple, so I have to add the path to the new PHP binary by writing this into my ~/.profile or ~/.bash_profile (or equivalent):

I want to confirm that I have the freshly installed PHP executable to do my bidding, so I write into the terminal shell and press enter:

Thus rendering:

Step 2 – enable dynamic hosting under ~/Sites

To allow my hosts to reside in the ~/Sites folder, I uncomment these three lines in /private/etc/apache/httpd.conf:

And then this line in /private/etc/apache2/extra/httpd-userdir.conf:

I create the file /private/etc/apache/users/YOURUSERNAME.conf. I notice that this requires root privileges, so I use the sudo command. Lines 15 to 31 are the interesting ones, as they are using wild cards in VirtualDocumentRoot, thus allowing me to resolve any combination of (in my case, maximum two) subdomains. This will be explained in the final step.

I create the ~/Sites folder. If it were already present, I would not have to do so. Obviously.

Restart the Apache server:

If I were to type:

in my terminal window, I would expect to see:

Step 3 – add a local DNS server

I want domains like, and to end up on my local web server and finally in nice and warm web roots. As if by magic. For this, I need my development machine to respond to DNS requests for any arbitrary domain using the .dev Top Level Domain.

Dnsmasq, I choose you (why not a .PAC file?):

When the installation is done, I copy the template configuration file:

I insert the following line into /usr/local/etc/dnsmasq.conf (I can safely delete all existing lines if I want to):

This instructs Dnsmasq to respond to all requests ending in .dev with

I also run these three commands to copy the deamon config file to its proper place, change the owner and load dnsmasq immediately:

So far, I have told my machine to respond nicely, now I have to tell it to send DNS queries for .dev (and only .dev) to Dnsmasq. I do this by creating a resolver configuration. First I create the directory:

Then I create the configuration file and add the configuration to it:

Step 3a – testing it

This is the part where I test and see if the stuff works. I start by creating a nifty folder structure for my testproject in ~/Sites:

Then I create an index.html for each subdomain (site, api and shop), and fill it with some meaningful text:

Now, when I run a few cURL requests:

So What?

I am able to create new web projects fairly quickly, just by creating a few folders in ~/Sites, adhering to this general pattern


Post Scriptum

Why do I use Dnsmasq and not a simple .PAC file? Well, while a .PAC file certainly will do the job for browsing the .dev sites I create, in a browser and certain other user agents, it does not play well with some (actually most) of the PHP-based testing frameworks I am using.

When testing a site from the command line using Behat, Mink and Goutte, any .PAC file implemented through OSX’s Network settings, or in a browser plugin, will not work; cURL is used, and it simply doesn’t know about this file.

This is some very tiny text to let you know that you have reached the end of this post.

More to read about Software engineering