Part 2: macOS 10.13 High Sierra Web Development Environment
This is an updated version of our prior OS X development series. The newly released macOS 10.13 High Sierra requires significant changes compared to prior releases, necessitating a thorough revamp in the process. The main change is why now use Homebrew's Apache, rather than the built-in version, but it should continue to work on prior OS X versions.
In Part 1 of this 3-part series, we covered configuring Apache on macOS to work better with your local user account, as well as the installation process for installing multiple versions of PHP.
In this Part 2, we will cover installing MySQL, Virtual Hosts, APC caching, YAML, and Xdebug. After finishing this tutorial, be sure to check out how to enable SSL in Part 3 of the series.
This guide is intended for experienced web developers. If you are a beginner developer, you will be better served using MAMP or MAMP Pro.
Although not required for development of Grav, there are times you definitely need an installation of MySQL. In the original guide, we used the Oracle MySQL installation package. However, we now have switched to MariaDB which is a drop-in replacement for MySQL and is easily installed and updated with Brew. Detailed information on the HomeBrew installation process can be found on the mariadb.org site but the essentials are as follows:
Install MariaDB with Brew:
$ brew update $ brew install mariadb
After a successful installation, you can start the server ane ensure it autostarts in the future with:
$ brew services start mariadb
You should get some positive feedback on that action:
==> Successfully started `mariadb` (label: homebrew.mxcl.mariadb)
Download SequelPro and install it. (it's awesome and free!). You should be able to automatically create a new connection via the
Socket option without changing any settings.
It is advisable to change the MySQL server password and secure your installation. The simplest way to do this is to use the provided script:
Just answer the questions and fill them in as is appropriate for your environment.
If you need to stop the server, you can use the simple command:
$ brew services stop mariadb
Apache Virtual Hosts
A very handy development option is to have multiple virtual hosts set up for you various projects. This means that you can set up names such as
grav.mydomain.com which point to your Grav setup, or
project-x.mydomain.com for a project-specific URL.
Apache generally performs name-based matching, so you don't need to configure multiple IP addresses. Detailed information can be found on the apache.org site.
Apache already comes preconfigured to support this behavior but it is not enabled. First you will need to uncomment the following lines in your
LoadModule vhost_alias_module lib/httpd/modules/mod_vhost_alias.so
# Virtual hosts Include /usr/local/etc/httpd/extra/httpd-vhosts.conf
Then you can edit this referenced file and configure it to your needs:
$ open -e /usr/local/etc/httpd/extra/httpd-vhosts.conf
This file has some instructions already but the important thing to remember is that these rules are matched in order. When you set up virtual hosts, you will lose your older document root, so you will need to add back support for that first as a virtual host.
<VirtualHost *:80> DocumentRoot "/Users/your_user/Sites" ServerName localhost </VirtualHost> <VirtualHost *:80> DocumentRoot "/Users/your_user/Sites/grav-admin" ServerName grav-admin.test </VirtualHost>
As you set up your
.test virtual hosts, you may receive a warning such as
Warning: DocumentRoot [/Users/your_user/Sites/grav-admin] does not exist when restarting Apache. This just lets you know that the source directory listed for your virtual hosts is not present on the drive. It's an issue that can be resolved by editing this file with the corrected
We used to recommend using
.dev domain name, but since Chrome 63 forces all
.dev domains to use SSL, this guide has been updated to use
In the example virtualhost we setup above, we defined a
grav-admin.test. This by default will not resolve to your local machine, but it's often very useful to be able to setup various virtual hosts for development purposes. You can do this by manually adding entries to
/etc/hosts ever time, or you can install and configure Dnsmasq to automatically handle wildcard
*.test names and forward all of them to localhost (
First we install it with brew:
$ brew install dnsmasq
Then we setup
$ echo 'address=/.test/127.0.0.1' > /usr/local/etc/dnsmasq.conf
Start it and ensure it auto-starts on reboot in the future:
$ sudo brew services start dnsmasq
And lastly, add it to the resolvers:
$ sudo mkdir -v /etc/resolver $ sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/test'
Now you can test it out by pinging some bogus
ping bogus.test PING bogus.test (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.044 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.118 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.045 ms
Voila! we have successfully setup wildcard forwarding of all
*.test DNS names to localhost.
Caching in PHP is a big part of the performance equation. There are two types of caching typically available, and both have a big impact on speed and performance.
The first type of cache is called an opcode cache, and this is what takes your PHP script and compiles it for faster execution. This alone can typically result in a 3X speed increase!.
The second type of cache is a user cache, and this is a data-store that PHP can use to quickly store and retrieve data from. These typically run in memory which means they are transient, but very fast.
For PHP 5.6 and newer runs best with Zend OPcache by default but you can still use APCu Cache as a data store.
Install OPcache and APCu
Switch to PHP 5.6 mode, then run the following
$ sphp 56 $ brew install php56-opcache php56-apcu --build-from-source
If you have installed PHP 7.0, you will need to repeat the process:
$ sphp 70 $ brew install php70-opcache php70-apcu --build-from-source
For PHP 7.1:
$ sphp 71 $ brew install php71-opcache php71-apcu --build-from-source
For PHP 7.2:
$ sphp 72 $ brew install php72-opcache php72-apcu --build-from-source
Restart Apache with the standard
sudo apachectl -k restart command to pick up your changes.
Point your browser to
http://localhost/info.php and ensure you see a reference to Zend OPcache in the Zend Engine block.
Also scroll down and check you have an APCu section:
You actually have quite a few options when it comes to caching. There are also brews available for XCache, Memcache. To find an exhaustive list of all the available packages simply type:
$ brew search php56
$ brew search php70
$ brew search php71
$ brew search php72
With recent versions of Grav, we now make use of the native PECL YAML library that allow YAML processing to be done by highly efficient libYAML C library rather than by they Symfony PHP library. This can result in a 5X improvement in YAML processing times! Luckily this is a simple process to install for any PHP version:
for PHP 5.6:
sphp 56 brew install php56-yaml --build-from-source
and for PHP 7.0:
sphp 70 brew install php70-yaml --build-from-source
and for PHP 7.1:
sphp 71 brew install php71-yaml --build-from-source
and for PHP 7.2:
sphp 72 brew install php72-yaml --build-from-source
One of the most important aspects of any kind of development is the ability to debug and fix your code. PHP comes with limited support to dump variables or log to a file, but for more complex situations you need something more powerful. Xdebug provides is a debugging and profiling extension for PHP that provides an HTML-friendly output for the
var_dump() method that improves the readability of the default version.
It also provides other useful dumping methods as well as displaying stack traces. One of the best features however, is the ability to remote debug your code. This means you can set breakpoints, and step through your PHP code inspecting as you go. Full documentation on Xdebug contains extensive information about all the functionality available.
Installation of Xdebug is just as easy as the previous installation of APC or YAML:
For PHP 5.6:
sphp 56 brew install php56-xdebug --build-from-source
and for PHP 7.0:
sphp 70 brew install php70-xdebug --build-from-source
and for PHP 7.1:
sphp 71 brew install php71-xdebug --build-from-source
and for PHP 7.2:
sphp 72 brew install php72-xdebug --build-from-source
Again, you will need to use the
sudo apachectl -k restart command to pick up your changes. You should also check the
http://localhost/info.php to ensure that Xdebug information is displayed:
W00fz created a great tool for quickly enabling/disabling xdebug. Install this with brew:
$ brew install xdebug-osx
The default configuration that comes with the xdebug is probably not enough to work with your development environment. I've included a simple configuration file for PHP 7.0 that you can use and edit for each PHP version.
Simple edit your
$ open -e /usr/local/etc/php/7.0/conf.d/ext-xdebug.ini
and paste the following:
[xdebug] zend_extension="/usr/local/opt/php70-xdebug/xdebug.so" xdebug.remote_enable=1 xdebug.remote_host=localhost xdebug.remote_handler=dbgp xdebug.remote_port=9000
You will need to save this and restart apache to pick up the changes. Simple create a similar version for each of your PHP versions installed just ensure you also change the the path in the
zend_extension line to reflect the correct PHP version.
You should now be all set with a Rockin' PHP development environment! To find out how to enable SSL on Apache, check out Part 3 in the series.
NOTE: The brew installation actually creates configuration files in
/usr/local/etc/php/7.2/conf.d respectively. If you want to uninstall a PHP extension, simply rename the
.ini file to
.ini.bak and restart apache. Alternatively, you can simply use brew to uninstall it, and reinstall it again when you need it.