Installing Homebrew PHP extensions with PECL
Recently the homebrew/php tap was deprecated in favour of PHP versions taken directly from homebrew/core. With this deprecation however, all versions with pre-built extensions were removed. In this guide we'll take a look at how we can compile and add these extensions ourselves.
Prerequisites
For this guide, we’ll assume you’re running a PHP version installed from homebrew/core
. If you’re unsure, check what’s installed by running:
$ brew list | grep php
New versions would be listed as:
php ← the latest version
php@7.1
php@7.2
Old versions would be listed as:
php71
php72
php72-memcached
php72-opcache
[...]
If you haven’t made the switch, follow these excellent guides for removing and installing the right version(s).
Also make sure you have pkg-config
and zlib
installed. If these are missing, the extension will not be compiled properly.
$ brew install pkg-config zlib
Installing extensions
The preferred way to install extensions nowadays is through PECL. This can be accomplished with the pecl
command.
Install
To install an extension, run the following command.
$ pecl install <extension>
This command will…
- compile and install the extension in the PECL extension directory
- add the extension to your currently active PHP configuration (
php.ini
)
It will not…
- tell PHP about your PECL extension directory (one-time configuration)
Note: the install command might ask you for a few (path) settings, but usually you can safely accept the defaults and hit enter.
To verify the extension is correctly added in you PHP configuration, run php --ini
and open it. The newly installed extension will be on top of the file if you didn’t have an existing extension
entry before. Else it will be added below any previously added entry.
The extension is now installed and activated, but at this time PHP still can’t locate the compiled extension itself.
Configure the extension directory
To load extensions installed by PECL, we need to point the extension_dir
in our php.ini
to the extension directory created by PECL. This directory can be found by running:
$ pecl config-get ext_dir
Now uncomment and update the extension_dir
in your php.ini
:
extension_dir = /usr/local/lib/php/pecl/<php_api_version>
Verify
After installing an extension you should of course restart your webserver or PHP-FPM instance, depending on how you’re running PHP.
To verify the module is loaded on the CLI, run either:
$ php --info | grep <module>\\.
$ php --modules | grep <module>
If you’re running PHP-FPM, it’s likely the CLI version isn’t the same version as the one running your (web) application. If you want to be sure it’s loading properly, you could create an info.php
file, and open it in the browser with these contents:
<?php phpinfo() ?>
Both should show some entries for the newly installed extension.
When running multiple PHP versions
There are two minor caveats to keep in mind when running multiple PHP versions, or switching to a new version.
Different extension directories
Every minor PHP version has its own API version. This means that PECL will have its own extension directory per minor PHP version (7.1
, 7.2
, 7.3
, …). For example:
/usr/local/lib/php/pecl/20160303 ← 7.1
/usr/local/lib/php/pecl/20170718 ← 7.2
/usr/local/lib/php/pecl/20180731 ← 7.3
Make sure you don’t mix them up when adding them as the extension_dir
in your php.ini
. You can always check the current API version by running:
$ php -i | grep 'PHP API'
Compile for each API version
Furthermore, it’s required to compile extensions for every PHP API version. One might think we can cheat the system, and just compile extensions and point all PHP versions to that directory. Trying to do so will result in errors however.
The solution is to switch to the PHP version you want to use, and install the extension again. This will add it to the current version, and will install the compiled extension in the correct API version directory.
An example
As an example, we’ll install the Memcached PHP extension. We use this for communicating with the Memcached daemon, which is a memory caching system comparable to Redis.
Install
To compile the Memcached extension — not to be confused with the outdated Memcache one — we first need to install libmemcached
:
$ brew install libmemcached
Compile and install the extension:
$ pecl install memcached
You can safely hit enter when the installation scripts asks you for paths and configuration options:
libmemcached directory [no] :
zlib directory [no] :
use system fastlz [no] :
...
Now you’ve installed the memcached
extension, provided you’ve pointed your extension_dir
to the right path, and restarted your web server or PHP-FPM daemon.
Verify
To verify the module is loaded, run:
$ php --info | grep memcached\\.
It should output a bunch of Memcached-related configuration entries.
Finally
Only thing left is getting the Memcached service itself up and running:
$ brew install memcached
To start the daemon, launch it with Homebrew Services:
$ brew services start memcached
This will start Memcached, and will also launch it when logging in. To have it run only once, launch it with run
instead of start
, or use the memcached
command for more direct control.
You’re all set. Start caching 💪
Having trouble?
A few paths that might help when having trouble…
PHP installations
/usr/local/opt/php/<version>
PHP configurations
/usr/local/etc/php/<version>
PECL extension directories
/usr/local/lib/php/pecl/<version>
Updated on October 12, 2019: Fixed a few typos, updated with 7.3 examples, and add pkg-config
and zlib
prerequisites after a tip on Twitter.