[php-src] PR #24192: Link the CLI into php-fpm, so that a php symlink to php-fpm runs the CLI

From: Date: Thu, 08 Oct 2026 11:39:26 +0000
Subject: [php-src] PR #24192: Link the CLI into php-fpm, so that a php symlink to php-fpm runs the CLI
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-39250@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/24192 Author: mnapoli This is an alternative to #23558, which it would replace, following the discussion of the RFC on internals: https://externals.io/message/132806 Instead of linking FPM into the php CLI binary, this links the CLI into php-fpm, as suggested by Nicolas Grekas and Jakub Zelenka. Larry Garfield pointed out that the first approach privileged FPM inside the CLI binary. Here the php binary is unchanged, and the same approach can be used by any other SAPI that wants to ship the CLI (like FrankenPHP does through embed since #21385). When the CLI SAPI is built, its objects (PHP_CLI_SHARED_OBJS, introduced by #21385) are linked into php-fpm. php-fpm then runs as the CLI when invoked under the name php, optionally followed by a digit: ```sh php-fpm -y /etc/php-fpm.conf # FPM, as today ln -s php-fpm php ./php script.php # CLI ln -s php-fpm php8.7 ./php8.7 -v # CLI ``` Under any other name (php-fpm, php-fpm8.7, php-cgi…), php-fpm behaves as before. ### Design - No configure option: the CLI is linked into php-fpm whenever the CLI SAPI is built, which is the default. The CLI has no libraries of its own, so php-fpm gains no dependency, only the CLI code (about 150 KB on a minimal build). With --disable-cli, php-fpm is built as before. - The mode is selected by the executable name only, there is no flag. FPM's argument parsing is untouched (no clash between the CLI and FPM options, such as -F), and argv reaches the CLI unchanged. - The name rule is php, optionally followed by a digit (php8.3 on Debian, php83 on Alpine), so that php-cgi, phpdbg, phpize, etc. are not affected. - Both SAPIs define PHP_FUNCTION(apache_request_headers), which is a duplicate symbol once linked together. FPM's C symbol is renamed to fpm_request_headers (the name suggested in the review of #23558), in a separate commit. The PHP functions are unchanged. ### Shipping a single executable PHP_BINARY is resolved with realpath(). To ship a single executable for both SAPIs, install the php-fpm binary as php, and php-fpm as a symlink to it. In CLI mode, PHP_BINARY then points to php, so scripts that run PHP_BINARY (Composer restarting itself, PHPUnit process isolation…) keep running the CLI. With the opposite layout (php as a symlink to php-fpm), they would start FPM. This is documented in UPGRADING. ### Tests - New sapi/fpm/tests/main-cli.phpt, skipped when PHP is built with --disable-cli. - The whole sapi/cli/tests suite passes when run through a php symlink to php-fpm, and sapi/fpm/tests passes. The RFC will be updated to describe this approach: https://wiki.php.net/rfc/single-binary-cli-fpm

« previous php.git-pulls (#39250) next »