解决 pcntl 相关函数报错的问题
问题
在macOS
环境中,命令行运行php artisan horizon
报错:
Call to undefined function Laravel\Horizon\pcntl_async_signals()
原因1:缺少pcntl
扩展
首先查看pcntl
扩展是否已经安装:
php --ri pcntl
如果未安装,为命令行使用的 PHP 安装pcntl
扩展后重试。
原因2:函数被禁用
如果原因1已经排除,可能是相关函数被禁用。 找出当前使用的php.ini
文件:
php --ini
# 输出
Loaded Configuration File: /Library/Application Support/appsolute/MAMP PRO/conf/php7.4.1.ini
打开当前使用的php.ini
文件,即: /Library/Application Support/appsolute/MAMP PRO/conf/php7.4.1.ini
,搜索disable_functions
,查看pcntl
相关的函数是否被禁用。
原因3:多个 php.ini
文件的原因
如果原因1、原因2都已经排除,可能是因为加载了多个php.ini
文件。
解决方案
查看现有的php.ini
文件:
php --ini
# 输出
Configuration File (php.ini) Path: /Applications/MAMP/bin/php/php7.4.1/conf
Loaded Configuration File: /Library/Application Support/appsolute/MAMP PRO/conf/php7.4.1.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
可以看到相关的php.ini
文件有多个:
/Applications/MAMP/bin/php/php7.4.1/conf 目录下的 php.ini文件
/Library/Application Support/appsolute/MAMP PRO/conf/php7.4.1.ini
找出这些php.ini
文件,确保每个php.ini
文件中都有这样一行:
extension=pcntl.so
排查思路
如果以上三个解决方案都不可行,可以按以下思路排查。
定位到抛出异常的 PHP 文件,比如作者遇到的是以下代码抛出的异常:
protected function listenForSignals()
{
pcntl_async_signals(true);
......
加入代码,输出这段代码使用的 PHP 信息:
protected function listenForSignals()
{
# 输出PHP版本
dump(PHP_VERSION);
# 输出pcntl扩展是否已经加载
dump(extension_loaded('pcntl'));
# 输出当前使用的php.ini文件
dump(php_ini_loaded_file());
pcntl_async_signals(true);
......
输出:
Horizon started successfully.
"7.4.1"
true
"/Library/Application Support/appsolute/MAMP PRO/conf/php7.4.1.ini"
"7.4.1"
false
"/Applications/MAMP/bin/php/php7.4.1/conf/php.ini"
Error
Call to undefined function Laravel\Horizon\pcntl_async_signals()
可以看出第二个php.ini
文件中,没有加载pcntl
扩展。