phpstorm.dev

PHP ecosystem insights

PHP knowledge

Versioned PHP knowledge with primary sources and explicit verification dates.

Source checks through 2026-10-14 · 56 sources

Verified 2026-10-10 discussion Permanent entry

Single binary for CLI and FPM proposal

Under discussion; not accepted. The RFC page (version 0.2, dated 2026-10-08, author Matthieu Napoli) and the official RFC index both list it as under discussion. The proposed version is PHP 8.7. The voting thread reads "tbd". The page's vote widget shows 0/0/0 and "This poll has been closed". That is the wiki template, and no vote has been opened.

Proposal (version 0.2, 8 October)

Version 0.2 reverses the direction of version 0.1. Instead of linking FPM into php, it links the CLI SAPI into the php-fpm executable:

PHP_BINARY is the executable's real path (symlinks are resolved). A distribution that wants a single executable should therefore install it as /usr/bin/php, with php-fpm as a symlink to it. Then PHP_BINARY runs the CLI in both modes, while FPM is still started as php-fpm, so service files, process titles and graceful reload (SIGUSR2, which re-executes through the symlink) keep working. Tools that read /proc/<pid>/exe see php for FPM processes. The opposite layout (php as a symlink to php-fpm) makes PHP_BINARY start FPM; the RFC says this will be documented in UPGRADING.

Listed backward-incompatible changes, only for builds with both SAPIs: php-fpm invoked as php/php8.7 now runs the CLI, php-fpm grows by about 150 KB in a minimal build, and FPM's C function zif_apache_request_headers is renamed zif_fpm_request_headers (the PHP functions apache_request_headers() and getallheaders() are unchanged). There is now a single primary vote needing a 2/3 majority; the secondary default-on vote of version 0.1 is gone. The RFC lists no open issues. It cites the PHP 8.6 change that made the CLI available to the embed SAPI (PR #21385), which FrankenPHP uses, as the model.

The RFC also records two rejected alternatives: a php-fpm --cli option (it would touch FPM's argument parsing, and some letters such as -F mean different things in the two SAPIs), and a shared libphp.so (a much larger build and packaging change that adds dynamic linking at start).

Version 0.1 (6 October)

Version 0.1 proposed an --enable-cli-fpm configure option that linked FPM into php, selected with a leading --fpm argument or a php-fpm* name. It had a secondary simple-majority vote on whether to enable the option by default. Its implementation, PR #23558. The RFC now lists that design under rejected features.

Motivation and evidence

The author measured Bref (PHP on AWS Lambda) builds on PHP 8.5.11, Linux x86-64, by replacing php-fpm with a symlink to a combined executable. The zipped layer went from 24.3 MB to 19.9 MB and the unzipped layer from 89.9 MB to 64.5 MB. The median FPM cold start over 50 starts dropped from 280 ms to 211 ms (difference −70 ms, 95% CI −79 to −59); a control runtime that never starts FPM showed no difference. The RFC says ARM and other memory sizes were not measured, and that the gain on hosts with the image on local disk is likely smaller. These are the author's own benchmarks. The page does not say whether they were repeated with the version 0.2 build.

The new implementation is php-src PR #24192. On 2026-10-08 the GitHub API showed it as open, not a draft and not merged (created 11:39 UTC). PR #23558 was still open as well.

Discussion

The RFC was announced on 6 October. Replies that day were broadly positive and raised these points:

On 8 October the author agreed, opened PR #24192 and published version 0.2. Tim Düsterhus disagreed with the new direction, arguing that selecting a SAPI by executable name is hard to discover and surprising: a php-like name that does not match the rule (a custom p symlink, or php-8.7) would start FPM and possibly bind sockets, with no way out except renaming. Düsterhus also rejected the view that version 0.1 privileged FPM, and preferred an explicit flag on php (--fpm, or for example --mode=fpm), by analogy with -S for the built-in server.

On 10 October Marc Henderkes agreed with Düsterhus and gave three reasons: php --fpm <fpm-args> is clearer than renaming the binary, php-fpm usually lives in /usr/sbin, which users should not normally call directly, and php-fpm php-cli <cli-args> is awkward. Henderkes did not share Garfield's concern about privileging FPM, and preferred a top-level --fpm flag over --mode=fpm.

Later on 10 October (19:07 UTC) Levi Morrison suggested another alternative, replying to the version 0.1 announcement: building the Zend engine as a shared library, libzend.so. Morrison said this used to be possible to build and assumed it was partly removed for performance. It would also let most extensions link their symbols against libzend.so instead of leaving them undefined for the executable to provide. Morrison said the performance cost would need measuring, but would personally prefer this solution if it is viable. The RFC's rejected alternative is a shared libphp.so with small php and php-fpm executables. The message does not say how libzend.so would relate to that option, and this page does not treat them as the same proposal.

As of 22:00 UTC on 10 October the author had not replied to either message. The RFC page was still version 0.2, and PR #24192 was still open, not a draft and not merged (last updated 2026-10-08).

Limitations

This page summarises a version 0.2 proposal that changed fundamentally two days after version 0.1, with two participants on the list now preferring an explicit --fpm flag on php and a third suggesting a shared libzend.so instead. The direction, the name-matching rule and the handling of PHP_BINARY can change before a vote, and nothing here is in released PHP.

Related: support windows.