Ubuntu 16.04: How to manually compile PHP 7.2 with ZTS enabled and the pThreads module installed

Working with cutting-edge tech at RapidSpike our dev team often faces tricky, involved technical problems.

Our solutions to these issues might be of use to other developers – so we’ve asked the team to share their work on our blog. If you’re a developer and this post has helped you – let us know!

 

In a previous post, we talked about how to install PHP 7.0 with ZTS enabled, so as to be able to install pThreads and achieve multi-threading with PHP. If you haven’t read it, I urge you to before going further with this post!

In the other post I mentioned that the easiest way to do this is to install a PHP package with ZTS pre-enabled called `php7.0-zts`. This package can be found in an experimental and unsupported PPA provided by Ondřej Surý called `ondrej/php-zts`. However, this method ‘locks’ you to PHP 7.0 which isn’t ideal if you want to stay up-to-date and use the latest PHP versions (7.2 at time of writing). By 3rd December 2018 version 7.0 will be officially unsupported so being able to upgrade is essential.

In this post I’ll explain how to manually compile PHP 7.2 with the necessary options to enable ZTS and install pThreads, giving you access to true multi-threading in PHP. It’s a little more involved than simply installing a PPA package but it’s a good process to go through if you’re interested in knowing a bit more about how PHP works under the hood.

Installation

These steps will build PHP with access to the `Thread` class, which in turn gives access to true multi-threading with PHP!

Prerequisite: a Virtual Machine or server running a clean install of Ubuntu 16.04.

1. Update everything and install the required packages

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install libzip-dev bison autoconf build-essential pkg-config git-core libltdl-dev libbz2-dev libxml2-dev libxslt1-dev libssl-dev libicu-dev libpspell-dev libenchant-dev libmcrypt-dev libpng-dev libjpeg8-dev libfreetype6-dev libmysqlclient-dev libreadline-dev libcurl4-openssl-dev

2. Download, unpack and build PHP 7.2.2 from its source

wget https://github.com/php/php-src/archive/php-7.2.2.tar.gz
tar --extract --gzip --file php-7.2.2.tar.gz
rm -f php-7.2.2.tar.gz

cd php-src-php-7.2.2
./buildconf --force

3. Configure PHP with the correct settings

These are the PHP configuration settings.
Note the last line’s

CONFIGURE_STRING="--prefix=/etc/php7 --with-bz2 --with-zlib --enable-zip --disable-cgi \
--enable-soap --enable-intl --with-openssl --with-readline --with-curl --enable-ftp \
--enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-sockets \
--enable-pcntl --with-pspell --with-enchant --with-gettext --with-gd --enable-exif \
--with-jpeg-dir --with-png-dir --with-freetype-dir --with-xsl --enable-bcmath \
--enable-mbstring --enable-calendar --enable-simplexml --enable-json --enable-hash \
--enable-session --enable-xml --enable-wddx --enable-opcache --with-pcre-regex \
--with-config-file-path=/etc/php7/cli --with-config-file-scan-dir=/etc/php7/etc \
--enable-cli --enable-debug --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data \
--with-mcrypt --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-shmop \
--enable-pthreads --with-tsrm-pthreads --enable-maintainer-zts"

./configure $CONFIGURE_STRING
make && sudo make install

4. Check ZTS is enabled (this should return an integer of ‘1’)

/etc/php7/bin/php -r "echo PHP_ZTS;"

5. Setup `phpize` and `php-config` for installing pThreads

chmod o+x /etc/php7/bin/phpize
chmod o+x /etc/php7/bin/php-config

6. Download, configure and install pThreads from source

Clone into the current directory from earlier – ‘php-src-php-7.2.2’.
Check the repo for supported PHP versions.

git clone https://github.com/krakjoe/pthreads.git

Then move into the new ‘pthreads’ directory.

cd pthreads
/etc/php7/bin/phpize
./configure --prefix='/etc/php7' --with-libdir='/lib/x86_64-linux-gnu' --enable-pthreads=shared --with-php-config='/etc/php7/bin/php-config'
make && sudo make install

7. Check that pThreads is installed (this should return an integer of ‘1’)

/etc/php7/bin/php -r "print_r(class_exists('Thread'));"

8. Finally configure the CLI settings

Move out of ‘pthreads’ and back into the ‘php-src-php-7.2.2’ directory.

cd ..
mkdir -p /etc/php7/cli/
cp php.ini-production /etc/php7/cli/php.ini

echo "extension=pthreads.so" | sudo tee -a /etc/php7/cli/php.ini
echo "zend_extension=opcache.so" | sudo tee -a /etc/php7/cli/php.ini

Set up the CLI path.

rm /usr/bin/php
ln -s /etc/php7/bin/php /usr/bin/php

 

Testing

Head over to the old blog post to see how to test that all of this works. It’s the same test process 😀

 

Extra Packages

Unfortunately you’ll now need to install all extra PHP packages manually rather than using a package manager. For example to install `mcrypt` you must do the following:

git clone https://github.com/php/pecl-encryption-mcrypt.git
cd pecl-encryption-mcrypt
/etc/php7/bin/phpize
./configure --prefix='/etc/php7' --with-libdir='/lib/x86_64-linux-gnu' --with-php-config='/etc/php7/bin/php-config' --enable-mcrypt=shared
make && sudo make install
echo "extension=mcrypt.so" | sudo tee -a /etc/php7/cli/php.ini