Open-source project
php-build/php-build avatar
php-build/php-build

php-build, and how a machine ends up with four PHP versions on it

Builds PHP so that multiple versions can be used side by side.

1,050 stars157 forksShellMIT

At a glance

What is it?
php-build is a shell utility that compiles PHP from source so that several versions can live side by side, with the build options and the PECL extensions given as environment variables on the command line. It is a phpenv plugin first and a standalone tool second, and its structure is borrowed from ruby-build.
Who is it for?
Adopt php-build if you need more than one PHP version on a machine, or a PHP version that your distribution does not package, and you are willing to compile from source. Do not adopt it if a distribution package or a container image would do, because compiling PHP is slow and leaves you responsible for the build dependencies.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A builder, not a version manager

php-build is a utility for building versions of PHP so they can be used side by side with each other, and the overall structure is loosely borrowed from Sam Stephenson's ruby-build.

That borrowing is the design. ruby-build compiles a Ruby from source into a directory of your choosing, and phpenv then uses those directories as the available versions. php-build does the same for PHP, and the model has two halves: a builder that produces a tree of PHP installations, and a version manager that switches between them.

The tool itself is a shell utility, and the primary language of the repository is Shell. It is MIT licensed, it publishes no GitHub releases, and the last push was on 2026-10-07 with the repository not archived. The homepage is php-build.github.io.

The audience is two kinds of user. The first is a developer on a Mac or a Linux box who needs to test an application against a PHP version their distribution does not ship, and who wants that version to be a directory rather than a system wide change. The second is a CI system that needs a reproducible PHP for each job, where compiling from source is slower than installing a package but gives a version that is exactly the one the test matrix asks for.

Both of those are cases where the awkwardness of a source build is worth paying for, and they are the cases the tool was written for.

One command, and the environment variables that shape it

The usage section gives a single command, and it is dense with information.

bash
PHP_BUILD_CONFIGURE_OPTS="--with-gmp" PHP_BUILD_INSTALL_EXTENSION="raphf igbinary pecl_http redis ssh2 xdebug" phpenv install -v -k 8.5.2

The example adds gmp support and installs the latest PECL extensions raphf, igbinary, pecl_http, redis, ssh2 and xdebug, with verbosity enabled and without running make clean after installing PHP version 8.5.2.

So the interface is: the version you want as the last argument, the configure flags in an environment variable, the extensions in another environment variable, and the flags in between. Nothing is a configuration file. Every build is a command line, which is exactly what you want in CI and in a shell history.

The two environment variables are the part worth understanding. PHP_BUILD_CONFIGURE_OPTS is passed through to the configure script, so anything configure accepts can be set, and PHP_BUILD_INSTALL_EXTENSION is a space separated list of PECL extensions to install on top of the core build.

The flag behaviour is the other half. The -v turns on verbosity, and the -k means the build does not run make clean afterwards, which the description explains as it doesn't run make clean after installing. That flag exists for a reason: a clean build is slower, and when you are iterating on a configure option locally, skipping the clean is the difference between a fast and a painful rebuild.

The version argument, 8.5.2 in the example, is a definition rather than a raw version string, and the definitions live in the share directory of the repository.

As a phpenv plugin, which is the standard way

The installation section starts with the phpenv route, and the project is clear that this is the standard way.

The installer is a curl piped to bash.

bash
curl -L https://raw.githubusercontent.com/phpenv/phpenv-installer/master/bin/phpenv-installer \
    | bash

That installs phpenv in $HOME/.phpenv, which is the default value of the PHPENV_ROOT environment variable, and it installs phpenv plus php-build and other plugins, updating all of them when you want to.

The manual route is there for people who do not want a script from the internet deciding what to install. You locate your phpenv directory, and clone the Git repository into the phpenv plugins directory.

bash
git clone https://github.com/php-build/php-build.git $HOME/.phpenv/plugins/php-build

Then you use php-build as a phpenv plugin with `phpenv install <definition>`, and the built version is installed into $HOME/.phpenv/versions/<definition>.

That last path is the whole point of the layout. Each PHP version is a self contained directory under versions, named after the definition you asked for, and phpenv switches between them by pointing at one. Nothing is installed into the system, and two versions of PHP can coexist without either of them knowing about the other.

For a CI job the same mechanism is the answer to the question of how to test against four versions of PHP without four machines.

As a standalone tool, with a prefix you can move

The standalone route is for people who want the builder without the version manager.

You clone the Git repository, change into the directory and run the install script.

bash
git clone https://github.com/php-build/php-build.git
bash
./install.sh

That installs php-build to the default prefix /usr/local. To install to a different location you set the PREFIX environment variable.

bash
PREFIX=$HOME/local ./install.sh

And if you do not have permissions to write to the prefix, you have to run install.sh as superuser, either via su -c or via sudo.

The PREFIX variable is worth a moment, because it is the difference between a tool you can install without root and one you cannot. A CI image that installs into $HOME/local as a non-root user needs no privilege escalation at all, and the script supports that without modification.

The repository also has an uninstall.sh, which is the counterpart of install.sh, and an install-dependencies.sh, which is the script to look at before a first build.

That last one matters. Building PHP from source needs a compiler, a build tool, and a set of libraries, and the versions and names of those differ between distributions. A script in the repository that installs the dependencies for you is the difference between a working first build and a first build that fails on a missing header.

The repository as a shell project, with a Vagrantfile

The top level listing is that of a project that grew up in the shell ecosystem, and a few entries are worth naming.

There is a bin directory for the executables, a share directory for the definitions that map a version string to a build recipe, a man directory for the manual pages, and a tests directory. The scripts around them are install.sh, uninstall.sh, install-dependencies.sh, build-openssl-1.0.sh for building an older OpenSSL, build-docs.sh, make-release.sh and run-tests.sh.

That OpenSSL script is a historical marker. PHP versions before a certain point need OpenSSL 1.0, which no current distribution packages, so a builder that supports old PHP releases has to build that dependency itself. It is a small file that represents a large amount of compatibility work.

The two other entries are a Vagrantfile and a vagrant-init.sh, and they explain how the project tests across environments. A builder that compiles against different libraries on different distributions needs more than one machine to be confident, and a Vagrant file is the conventional way to get that, back when it was the conventional way.

The build and test runner is a Travis configuration at the top level, and the changelog is a CHANGELOG.md with a make-release.sh script beside it. The project keeps a man page, which is a small sign of respect for people who want the tool documented in the way their shell expects.

Contributing through a channel that no longer exists

The contributing section is short, and one line in it is a time capsule.

Issue reports and pull requests are always welcome, and the channels listed are a Freenode channel, #php-build, and a Google group at groups.google.com for the php-build developers.

Freenode is long gone, and the project is a decade old in its current shape, so the IRC reference is a relic. The GitHub issue tracker is the live channel, and the project points at a CONTRIBUTING.md for the details.

The core team is named, and the names are worth recognising because they are the same people behind much of the PHP tooling world. Graham Campbell, Rogerio Prado de Jesus, Loïc Frering and Christoph Hochstrasser are listed as the people who review and merge contributions.

That review arrangement is the thing to notice. A project where a named group of maintainers merges everything, rather than a single maintainer or a rotating committee, tells you how a pull request is likely to be handled, and it is the reason the tool has stayed consistent for years across a lot of PHP versions.

The homepage is a GitHub Pages site, and the repository is MIT licensed with a LICENSE file. The project publishes no GitHub releases, so the version of php-build you get is whatever is in the branch you cloned, and the CHANGELOG.md is where the history lives.

Editorial conclusion

Adopt php-build if you need more than one PHP version on a machine, or a PHP version that your distribution does not package, and you are willing to compile from source. Do not adopt it if a distribution package or a container image would do, because compiling PHP is slow and leaves you responsible for the build dependencies. Before you run it, read install-dependencies.sh, because the build needs a compiler toolchain and libraries that the script expects to find, and note that the example in the project description installs xdebug, which is a development tool you probably do not want in a production build.

Frequently asked questions

What does php-build do?

It is a shell utility that builds versions of PHP from source so that several versions can be used side by side. Its structure is loosely borrowed from Sam Stephenson's ruby-build, and the built versions land in directories that phpenv then switches between.

How do I install php-build as a phpenv plugin?

The standard way is the phpenv installer, which installs phpenv in $HOME/.phpenv along with php-build and other plugins. Manually, you clone the repository into $HOME/.phpenv/plugins/php-build and then run `phpenv install <definition>`.

How do I build a specific PHP version with extensions?

Set PHP_BUILD_CONFIGURE_OPTS for the configure flags and PHP_BUILD_INSTALL_EXTENSION for a space separated list of PECL extensions, then run `phpenv install -v -k 8.5.2`, where -v enables verbosity and -k skips the make clean after the install.

Can I install php-build without phpenv?

Yes. Clone the repository, run ./install.sh, and it installs to the default prefix /usr/local. Set the PREFIX environment variable to install elsewhere, for example PREFIX=$HOME/local ./install.sh, and run the script as superuser if you cannot write to the prefix.

What licence is php-build released under?

It is released under the MIT licence, with a LICENSE file in the repository. The project publishes no GitHub releases, and the last push was on 2026-10-07.

Official sources

  1. Issues
  2. License: MIT
  3. php-build/php-build on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/php-build-php-build.svg)](https://hysenlabs.com/projects/php-build-php-build)

Was this useful?