Setting up PHP & MySQL on OS X Yosemite

October 20th, 2014 by Philip Iezzi 5 min read
cover image

How to set up a dev environment on OS X Yosemite (10.10) with Homebrew, PHP, MySQL, and Apache.

Homebrew

Homebrew is a package manager for OS X. Install it, as we'll need it later:

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

You'll also need the Xcode command line tools – at least version 6.1. Xcode is available on the Mac App Store as a free download. Don't forget to start up Xcode at least once after initial installation.

Initially and after every major OS X upgrade, you might need to reinstall the Xcode command line tools and accept the license aggreement:

$ xcode-select --install
$ sudo xcodebuild -license

Also, don't forget to create this missing symlink after upgrading to a new major OSX version:

$ sudo ln -s /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.10.xctoolchain

Once Homebrew is set up and you want to upgrade outdated packages, run:

$ brew update
$ brew upgrade

Remember to also run brew update && brew upgrade after upgrading to a new major OS X version.

List all installed packages:

$ brew list --versions

You should never be required to run brew as root using sudo!

PHP

Apple ships PHP 5.5.14 with OS X Yosemite but we're not going to use it and install the latest PHP 5.6 instead via Homebrew.

Tap homebrew/homebrew-php and all its dependencies (homebrew/homebrew-binary actually is no dependency but we might need it for binary PHP extensions):

$ brew tap homebrew/dupes
$ brew tap homebrew/versions
$ brew tap homebrew/homebrew-php
$ brew tap homebrew/homebrew-binary

Install PHP 5.6:

$ brew install php56 --without-snmp --with-cgi --with-debug --with-homebrew-openssl --with-imap --with-intl --with-mysql

Install some PHP extensions:

$ brew install php56-mcrypt
$ brew install php56-xdebug
$ brew install php56-imagick

Edit /usr/local/etc/php/5.6/php.ini and change settings appropriately. At a minimum, you should change:

date.timezone = "Europe/Zurich"
error_reporting  =  E_ALL
display_errors = On
pdo_mysql.default_socket=
mysql.default_socket=

We don't need to restart Apache after any modifications in php.ini as we are going to run PHP as CGI.

Composer

As a PHP developer for sure you are going to use Composer! We are not going to install it directly in /usr/local/bin as this directory is write-protected for the regular system user and we don't ever want to run Composer with sudo. Install it somewhere else and simply symlink it into /usr/local/bin:

$ mkdir -p /Applications/Tools && cd /Applications/Tools/
$ curl -sS https://getcomposer.org/installer | php
$ sudo ln -sf /Applications/Tools/composer.phar /usr/local/bin/composer

Upgrading Composer is terribly easy and does not require superuser rights:

$ composer self-update

MySQL

Download the "Mac OS X 10.9 (x86, 64-bit), DMG Archive" from official dev.mysql.com and install the following packages:

  • mysql-5.6.xx-osx10.9-x86_64.pkg
  • MySQLStartupItem.pkg
  • MySQL.prefPane

Then, open the pref pane and start the MySQL Server.

Update the path by editing /etc/bashrc (or ~/.bash_profile) and add:

export PATH=/usr/local/bin:/usr/local/mysql/bin:$PATH

at top of file.

Set up MySQL root password:

$ mysqladmin -u root password {new-password}
$ mysqladmin -u root -p{new-password} -h localhost password {new-password}
$ mysqladmin -u root -p{new-password} reload

Clear the history file by typing history -c so that {new-password} isn't in plain text on the disk!

Apache

OS X Yosemite (10.10) ships with Apache 2.4.9:

$ apachectl -v
Server version: Apache/2.4.9 (Unix)
Server built:   Sep  9 2014 14:48:20

This is great - no need for any other Apache installation! We just have to use the command line to start and stop it:

$ sudo apachectl stop|start|restart

Tune main Apache configuration in /etc/apache2/httpd.conf:

  • enable some modules (remove the leading # from these lines)
  • change the default user Apache is running as to your system user (like this you don't run into any permission trouble in your own projects)
  • include /etc/apache2/extra/httpd-vhosts.conf virtualhost configuration (see below)
  • set some environment variables
httpd.conf
# required for our PHP-as-CGI setup
LoadModule cgi_module libexec/apache2/mod_cgi.so
LoadModule actions_module libexec/apache2/mod_actions.so
# required for rewriting in .htaccess
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
 
# (...)
User youruser
Group _www
 
# (...)
Include /private/etc/apache2/extra/httpd-vhosts.conf
 
# (...)
SetEnv APPLICATION_ENV development

Configure PHP as CGI in /etc/apache2/other/php5.conf:

other/php5.conf
DirectoryIndex index.php index.html

# Homebrew PHP 5.6
ScriptAlias /phpcgi /usr/local/bin/php-cgi
Action php-cgi /phpcgi
AddHandler php-cgi .php

Comment out the examples in /etc/apache2/extra/httpd-vhosts.conf and add the following lines:

extra/httpd-vhosts.conf
# Override the default httpd.conf directives. Make sure to
# use 'Require all granted' to prevent 403 Forbidden message.
Options ExecCGI SymLinksIfOwnerMatch Indexes
AllowOverride Indexes AuthConfig Limit FileInfo Options=Indexes,MultiViews
Require all granted

#
# Use name-based virtual hosting.
#
NameVirtualHost *:80

#
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any block.
#
DocumentRoot "/Library/WebServer/Documents"
<Directory "/Library/WebServer/Documents">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Require all granted
</Directory>

You may then add all your VirtualHosts at the bottom of this file, e.g.:

extra/httpd-vhosts.conf
<VirtualHost *:80>
    DocumentRoot "/path/to/your/project/public"
    ServerName demoproject.test
</VirtualHost>

Now, add the project's hostname to /etc/hosts:

127.0.0.1       demoproject.test

Flush the local DNS cache after every modification in /etc/hosts:

$ dscacheutil -flushcache

Create a phpinfo.php for testing:

$ echo "<?php phpinfo();" > /Library/WebServer/Documents/phpinfo.php

Finally, test configuration and restart Apache:

$ apachectl configtest
$ sudo apachectl restart

Testing: