How to compile PHP from source on Debian/Ubuntu - Beginner's guide
Compiling PHP from its source is easier than it sounds. This is a more beginner-friendly guide on how to fetch its source from GitHub, install the necessaries for compilation, compile, and test run PHP.
PHP is readily available to download and install for many operating systems, including Windows, Debian/Ubuntu, Fedora, Mac OS, etc. Installing from such sources does not require compiling PHP, because they are already compiled, and ready to install. Further, they often contain various PHP extensions as decoupled install-able packages, so it is easy to customize the PHP run time with any combination of PHP extensions.
This guide focuses on compiling PHP from its source code, so it's easy to try out new features not yet released. The compiled form will be suitable for testing, rather than using them in a production server.
Looking for a TL;DR? A short version of the guide for the copy-paste pleasure is available at the TL;DR section.
-
The initial setup of installing the build tools (such as compilers and libraries) will take about five minutes. On a fresh Ubuntu 21.04 installation, it will require downloading ~210 MB of files. This is a one-time setup.
-
The Git repository of PHP in
master
branch (the branch for the latest and upcoming version) is around 420 MB at the time of writing. Once the Git repository is cloned, new changes can be pulled without having to download the whole repository over and over again. -
Building the configuration script and configuring the build will take about a minute. This process is mostly checking if all required dependencies are present in the system.
-
Compiling PHP can take anywhere from 2 minutes to 15-20 minutes, depending on the CPU core/thread count and the speed. On an 8-core 16 thread CPU at 2.9 GHz, it usually takes 2 minutes to complete. On the same CPU only utilizing just one CPU core, it takes ~16 minutes to compile.
1. Prerequisites
This guide is about compiling PHP from its source, on Debian 9 (Stretch) or later or Ubuntu 18.04 (Bionic Beaver) or later. This was tested to work on Debian versions up to 10 (Buster) and Ubuntu versions up to 21.04 (Hirsute Hippo).
Using Fedora/RHEL/CentOS ? See How to compile PHP from source on Fedora/RHEL/etc.
For the PHP source and build tools, a network connection capable to download ~ 600 MB will be necessary for the first run. Each subsequent build will be merely downloading the new commits from GitHub, and will be in the range of just few kilobytes to a megabyte or two. Make sure a disk space of at least 1 GB left.
The PHP source code is version-controlled using Git, and it is available to download over HTTP as a zip archive, or preferably using Git. The source code is available on GitHub, which is now the canonical source.
Optional: A virtual machine/container Compiling PHP and testing it out on a virtual machine makes everything so much easier and cleaner. If possible, make sure to follow the rest of the guide on a virtual machine or a container.
- For Windows users, a WSL2 running Ubuntu will be the most straight-forward approach.
- A virtual machine running Ubuntu/Debian, using Virtual Box, available on several operating systems including Windows and Mac OS.
- Running on Ubuntu docker image.
Optional: GitHub account with SSH Access It is possible to download the PHP source from the Git repository hosted on GitHub. It allows downloading the source code without any authentication.
To contribute to the PHP project, it requires a GitHub account to fork and make pull requests. It is a simple and one-off step to register and authenticate yourself to GitHub over SSH, and the process is documented at GitHub documentation.
2. Install Build Tools
All the basic tools to compile a minimal version of PHP can be installed in a single-go.
All commands that start with sudo
might require occasional password confirmation.
sudo apt install build-essential autoconf libtool bison re2c pkg-config
Depending on the existing software available on the system, it can download anywhere from 0 to ~220 MB.
build-essential
includes tools likegcc
, the GNU C compiler, andmake
, a utility to direct the compilation scripts.autoconf
is used to generate theconfigure
script that is used later in the compilation.libtool
is a tool that helps to manage and locate shared libraries.bison
is YACC-compatible parser generatorre2c
is a tool that is used to generate the PHP's lexer.
Note that these are the absolute minimum list of tools. Additional PHP extensions require additional dependencies, that are explained later in this guide under each extension.
3. Git Clone PHP Source
With the build tooling installed, it is now time to download the PHP source code from the Git repository.
The PHP source is available in the Git repository hosted at github.com/php/php-src.
git clone https://github.com/php/php-src.git --branch=master
If SSH is configured with GitHub, it is possible and to clone over SSH as well:
git clone git@github.com:php/php-src.git --branch=master
The --branch=master
option for Git narrows the clone operation to the master
branch. This can slightly reduce the download size, as it skips commits that does not belong to other branches.
A shallow clone can dramatically reduce the download size and clone time by not including any of the historical commits. This is ideal for a one-off test, but a shallow-clone does not allow making additional commits because the commit history is not available. To make a shallow clone, use the --depth=1
option:
git clone https://github.com/php/php-src.git --depth=1
Once it is finished, cd
to the php-src
directory that contains the PHP source:
cd php-src
4. Build configure
script
PHP source repository includes a script that generates a new ./configure
file.
./buildconf
5. Configure the build
the ./configure
script contains dozens of option to customize the PHP build.
Running ./configure --help
shows the entire list of options available to use.
./configure --help
The flags shown in the ./configure --help
follow a pattern of --enable-XYZ
, --disable-XYZ
, or --with-XYZ
. It accepts multiple flags, and is often a very long one in most PHP setups primed for production use.
example
./configure --enable-ftp --with-openssl --disable-cgi
--enable-XYZ
If the flag is passed, the extension/SAPI with name XXX
will be enabled. Using --enable-XXX=shared
pattern makes the extension to be compiled to a separate file so it can be enabled/disabled from the PHP INI files.
For example, running ./configure --enable-ftp
enables the FTP extension. running ./configure --enable-ftp=shared
enables the extension to be compiled as a shared extension; the extension will be compiled to a separate .so
file (.dll
in Windows), so it can be enabled/disabled using a PHP configuration file.
Not all extensions support compiling to a shared extension.
In addition to extensions, the --enable-XYZ
options are available for Server APIs (SAPIs) and specific features as well. Notably, the --enable-zts
enables thread-safety feature in the build.
--with-XYZ
This option is similar to --enable-XYZ
pattern that they enable various PHP extensions and features. Note these extensions/features often require additional dependencies.
For example, the OpenSSL extension, enabled with ./configure --with-openssl
depends on the development files of the OpenSSL library. In Ubuntu/Debian systems, they can be easily installed with the libssl-dev
package. The -dev
suffix to the package name indicates that it is a development package. To fulfill the requirements for OpenSSL extension, install libssl-dev
package:
sudo apt install libssl-dev
Appendix: Extension Dependencies An up-to-date list of extension requirements are listed in Appendix: Extension Dependencies section of this guide.
--disable-XYZ
and --without-XYZ
The opposite of --enable-XYZ
flags. The presence of this flag means PHP is configured to include that extension/feature/SAPI by default, unless the --disable-XYZ
option is passed.
Additionally, the --disable-all
flag disables all extensions, which allows a clean slate for individual extensions to be enabled with --enable-XYZ
flags.
By default, PHP compiles with SQLite support built-in. Disabling the SQLite3 extensions makes it possible to compile PHP without having to install SQLite3 dependencies.
./configure --without-sqlite3 --without-pdo-sqlite
Subsequent builds
Crafting the ./configure
command is cumbersome. When the ./configure
script is run, it saves the command to a ./config.nice
file, that executes the exact same command as before, plus append additional options.
After the first ./configure
run has completed, using the ./config.nice
file helps to avoid typing the same ./configure
options again and again.
./config.nice
6. Compile!
Once the ./configure
/./config.nice
script has completed, it is now time to run the compiler.
Depending on the CPU cores and threads available, this can take anywhere in the range from 2 minutes to 15-20 minutes.
make -j $(nproc)
The make
command is used to run the compilation using the C compiler. It accepts a -j
parameter, that can be used to configure parallel processing. Output of the nproc
command, which returns the number of available CPU threads in the system is then set for the make -j
parameter.
If the -j
option is not present, it will use a single CPU thread by default. To set a specific number of threads, simply specify the number for the -j
option:
make -j4
7. Install/try it out
The compiled binaries will be available in the ./sapi
directory. To immediately run the PHP CLI, for example, call the ./sapi/cli/php
binary.
./sapi/cli/php -v
PHP's interactive CLI is opened using the -a
parameter:
./sapi/cli/php -a
Alternately, the compiled PHP version can be installed on the system, so other tools can easily use the php
binary in PATH.
sudo make install
Appendix: Extension Dependencies
Following are command-line arguments passed to the ./configure
script to enable/disable/configure PHP extensions and features.
Core extensions
The following extensions are PHP core extensions, and cannot be disabled. Older PHP versions might have had a flag to toggle this extension, but they are not valid anymore for these extensions.
Extension | Notes |
---|---|
Date | |
Hash | Core extension since PHP 7.4 |
JSON | Core extension since PHP 8.0 |
PCRE | Pass --without-pcre-jit to Just-In-Time compilation. Since PHP 7.3, it uses PCRE2 |
Reflection | |
SPL | Core extension since PHP 5.3 |
Enabled by default
The following extensions are enabled by default, but can be disabled if necessary. The --disable-all
flag also disables all of them.
Extension | Disable flag |
---|---|
Ctype | --disable-ctype |
Fileinfo | --disable-fileinfo |
Filter | --disable-filter |
Opcache | --disable-opcache , or --disable-opcache-jit to disable JIT |
PDO | --disable-pdo |
Phar | --disable-phar |
POSIX | --disable-posix |
Session | --disable-session |
SimpleXML | --disable-simplexml |
SQLite | --without-sqlite3 |
Tokenizer | --disable-tokenizer |
XML | --disable-xml |
XMLReader | --disable-xmlreader |
XMLWriter | --disable-xmlwriter |
Disabled by default
Compiling additional extensions often require its dependencies in place. Here is a list of PHP extensions and their dependencies, and the ./configure
flag to enable it.
The Dependencies column lists the package names in Ubuntu/Debian repositories. Install them using the package manager:
sudo apt install <package-name>
Extension | Enable flags | Dependencies |
---|---|---|
BCMath | --enable-bcmath |
none |
BZ2 | --with-bz2 |
libbz2-dev |
Curl | --with-curl |
libcurl4-openssl-dev |
Exif | --enable-exif |
none |
FFI | --with-ffi |
libffi-dev |
FTP | --enable-ftp |
none |
GD* | --enable-gd --with-jpeg --with-webp --with-avif |
libzip-dev libpng-dev libjpeg-dev libwebp-dev libavif-dev |
GMP | --with-gmp |
libgmp-dev |
--with-imap --with-imap-ssl --with-kerberos |
libc-client-dev libkrb5-dev |
|
Intl | --enable-intl |
none |
LDAP | --with-ldap |
libldap2-dev |
Mbstring | --enable-mbstring |
libonig-dev |
OpenSSL | --with-openssl |
libssl-dev |
PDO: MySQL | --with-pdo-mysql |
none |
PDO: PgSQL | --with-pdo-mysql |
libpq-dev |
--with-pspell |
libpspell-dev |
|
Readline | --with-readline |
libreadline-dev |
Sockets | --enable-sockets |
none |
Sodium | --with-sodium |
libsodium-dev |
Soap | --enable-soap --with-libxml |
libxml2-dev |
Zip | --with-zip |
libzip-dev |
Notes
- GD extensions Avif image support (
--with-avif
/libavif-dev
) is only supported on PHP 8.1 and later. - Pspell extension was unbundled from PHP core in PHP 8.4.
- IMAP extension was unbundled from PHP core in PHP 8.4.
- OCI8 and PDO-OCI8 extensions were unbundled from PHP core in PHP 8.4.
TL;DR
The entire list of commands above are shortened below:
Initial run:
sudo apt install build-essential autoconf libtool bison re2c
git clone https://github.com/php/php-src.git --branch=master
cd php-src
./buildconf
./configure
make -j $(nproc)
sudo make install
Routine runs:
cd php-src
git pull --rebase
./buildconf --force
./config.nice
make -j $(nproc)
sudo make install
A ready-to-use ./config.nice
is also available.