调用未定义的函数 pcntl_fork() php-fpm nginx

Call to undefined function pcntl_fork() php-fpm nginx

我正在尝试在 php-fpm 中使用 pcntl_fork(),但它不可用,我得到:

Call to undefined function pcntl_fork()

尽管我在 php.ini 中注释掉了 disable_functionsphpinfo() 显示作者,php -m 还列出 pcntl。如果我从 cli 执行我的脚本,它就可以工作。我需要启用任何其他选项吗?

作为 MWE,我已经在 https://github.com/white-gecko/pcntl-mwe 处准备了一个最小的 docker 环境

docker pull whitegecko/pcntl-mwe

如果你 运行 它与 docker run -it --rm --name pcntl -p 8080:80 pcntl 你将在 http://localhost:8080/ 和 php 信息在 http://localhost:8080/phpinfo.php 中获得示例。它是一个 debian jessie 系统。

PCNTL 扩展仅限于在 CLI 中运行;您不能在其他服务器环境(fpm、mod_php 等)中使用它。

应该发生的是标记为 "cli" 的扩展只用于静态链接到 CLI 二进制文件,或允许在 CLI 中共享加载,并从针对其他 SAPI 的共享构建中省略(libphp7.so).

为 PHP 配置 PCNTL 的 autoconf (ext/pcntl/config.m4) 文件应该指示构建过程禁止在其他 SAPIS 中加载 PCNTL,碰巧 1) 它是不是很好,2)当 FPM 合并到 PHP 时没有考虑到这一点:因此 FPM 忽略它并无论如何与 PCNTL 源链接(如果在编译时启用扩展),其他 SAPI 将允许如果库是共享的,您可以加载它,因为 DSO(共享库)本身不强制执行 SAPI 限制。这些事情(FPM 链接和其他加载)都不应被允许,强制不受支持的 SAPI 加载 PCNTL 是一个糟糕的想法

当你 fork 一个进程时,你创建了一个调用 fork 的进程的 copy-on-write 克隆:在 Apache 或 FPM 内部,这意味着重复的文件(套接字)句柄,你不可能在子进程中优雅地管理它(因为您无法从 PHP 访问它们)。

这应该仅限于 CLI(和早期的 CGI)的原因是这些 SAPI 使用单一进程模型。虽然 FPM 在技术上是一个 CGI 接口,但它肯定不是单一进程,因此永远不会成为在用户领域进行分叉的合适环境。