I wanted a local PHP setup closer to the production servers I worked with, without waiting on MAMP. El Capitan already shipped with Apache, so I used that with Homebrew’s PHP 5.6 and MySQL.
The easy-to-miss step is pointing Apache at Homebrew’s PHP module instead of Apple’s bundled copy.
Why not the built-in PHP?
Apple’s bundled PHP is outdated and locked to specific modules. Homebrew gives you:
- Control over PHP version and extensions
- Easy upgrades without waiting for macOS updates
- Access to the full PECL extension ecosystem
- Configuration that matches production Linux servers
Prerequisites
You need Homebrew. Install from brew.sh:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Installing MySQL and PHP 5.6
Install MySQL, PHP 5.6, and mcrypt (which many PHP frameworks require):
brew install mysql
brew install php56
brew install php56-mcrypt
Homebrew installs PHP to /usr/local/opt/php56 and puts the Apache module at /usr/local/opt/php56/libexec/apache2/libphp5.so.
Configuring Apache for Homebrew’s PHP
macOS’s Apache config lives in /private/etc/apache2/httpd.conf:
sudo nano /private/etc/apache2/httpd.conf
Find the rewrite_module line. It’s commented out by default:
#LoadModule rewrite_module libexec/apache2/mod_rewrite.so
Uncomment it:
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
This enables URL rewriting (most PHP frameworks need it for clean URLs).
Find the php5_module line referencing the old built-in PHP:
#LoadModule php5_module libexec/apache2/libphp5.so
Replace it with the Homebrew version:
LoadModule php5_module /usr/local/opt/php56/libexec/apache2/libphp5.so
Finding your php.ini
Homebrew’s PHP config is at /usr/local/etc/php/5.6/php.ini. Adjust upload_max_filesize, memory_limit, or timezone there.
To find the active php.ini path:
php --ini
Starting MySQL and Apache
Start MySQL:
mysql.server start
Auto-start on boot:
brew services start mysql
Start Apache (requires sudo for port 80):
sudo apachectl start
Restart after config changes:
sudo apachectl restart
Open http://localhost in your browser. You should see the “It works.” page.
VirtualHosts for local domains
VirtualHosts map custom domain names (like myproject.local) to specific directories. Cleaner than localhost/subfolder/ URLs.
Enable VirtualHost support in /private/etc/apache2/httpd.conf:
# Virtual hosts
#Include /private/etc/apache2/extra/httpd-vhosts.conf
Uncomment it:
# Virtual hosts
Include /private/etc/apache2/extra/httpd-vhosts.conf
Edit the VirtualHost config:
sudo nano /private/etc/apache2/extra/httpd-vhosts.conf
Add your site:
<VirtualHost cors.kahwee:80>
DocumentRoot "/Users/kahwee/projects/cors"
ServerName cors.kahwee
ErrorLog "/private/var/log/apache2/cors.kahwee-error_log"
CustomLog "/private/var/log/apache2/cors.kahwee-access_log" common
</VirtualHost>
<Directory /Users/kahwee/projects/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
DocumentRootpoints to your project’s web root (for CakePHP, this might bewebrootorpublic)ServerNamematches the domain you want locallyAllowOverride Alllets.htaccessfiles work (needed for most PHP frameworks)Require all grantedallows access to the directory
Adding the domain to your hosts file
Apache won’t respond to cors.kahwee unless your system resolves it locally:
sudo nano /etc/hosts
Add:
127.0.0.1 cors.kahwee
Restart Apache:
sudo apachectl restart
Visiting http://cors.kahwee should load your project.
Testing PHP
Create a test file in your DocumentRoot:
echo "<?php phpinfo();" > /Users/kahwee/projects/cors/info.php
Visit http://cors.kahwee/info.php. You should see PHP’s configuration page showing version 5.6.
Common issues
“403 Forbidden”: Check the <Directory> permissions. Make sure Require all granted is set and the path matches your project directory.
PHP not executing: Verify LoadModule php5_module points to the Homebrew path, not the system path.
Changes not taking effect: Restart Apache after every config change: sudo apachectl restart
Why PHP 5.6 in 2016
Historical setup This guide targets macOS El Capitan in 2016. On a current macOS release, use
brew install phprather than the retiredphp56formula.
PHP 7 shipped in late 2015, but many frameworks and plugins weren’t compatible yet. PHP 5.6 was the safe choice for production work in mid-2016.
These days, I don’t run PHP locally at all. For this blog, a static site generator removed the database and server setup entirely.
One quick signal
Did this earn your time?
Thanks. That helps me decide what to improve next.


