Home » Php » pcntl – Call to undefined function pcntl_fork() php-fpm nginx

pcntl – Call to undefined function pcntl_fork() php-fpm nginx

Posted by: admin July 12, 2020 Leave a comment

Questions:

I’m trying to use pcntl_fork() in php-fpm but it is not available and I get:

Call to undefined function pcntl_fork()

Even though I’ve out-commented the disable_functions in the php.ini. phpinfo() shows the author and php -m also lists pcntl. If I’m executing my script from cli, it works. Is there any other option I need to enable?

As MWE I’ve prepared a minimal docker environment at https://github.com/white-gecko/pcntl-mwe resp.

docker pull whitegecko/pcntl-mwe

if you run it with docker run -it --rm --name pcntl -p 8080:80 pcntl you will have the example at http://localhost:8080/ and phpinfo at http://localhost:8080/phpinfo.php. Its a debian jessie system.

How to&Answers:

The PCNTL extension is meant to be restricted to operating in CLI only; You cannot use it in other server environments (fpm, mod_php, etc).

What is supposed to happen is that extensions marked as “cli” only are meant to be statically linked into CLI binary, or allowed to load shared in CLI, and omitted from shared builds targeting other SAPIs (libphp7.so).

The autoconf (ext/pcntl/config.m4) file that configures PCNTL for PHP is supposed to instruct the build process to disallow the loading of PCNTL in other SAPIS, it so happens that 1) it’s not very good and 2) this was not taken into account when FPM was merged into PHP: So that FPM ignores it and links with PCNTL source anyway (if the extension is enabled at compile time), and other SAPIs will allow you to load the library if it’s shared because the DSO (shared library) itself does not enforce SAPI restriction. Neither of these things (FPM linking, and others loading) should be allowed, and it’s a terrible idea to force an unsupported SAPI to load PCNTL.

When you fork a process, you create a copy-on-write clone of the process that called fork: Inside of Apache or FPM this means duplicated file (socket) handles which you cannot possibly gracefully manage in the child process (for you have no access to them from PHP).

The reason this is supposed to be restricted to CLI (and early CGI) is that these SAPIs use a single process model. While FPM is technically a CGI interface, it is certainly not single process, and so never will be a suitable environment for forking in user land.