我试图在我的新机器中运行PHPUnit测试,但我得到了这个错误:
PHP致命错误:未捕获异常"UnexpectedValueException",消息为"RecursiveDirectoryTerator::__construct(/usr/lib/PHP/pear/File/Iterator):无法打开/usr/lib/PHP/pear/File/Iterator/Factory.PHP:114 中的dir:打开的文件太多"
旧机器上的相同代码运行良好。。。
新机器环境:PHP版本:PHP 5.3.21(cli)旧版本:PHP 5.3.14
PHPUnit每次输出:
................EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE 65 / 66 ( 98%)
E
Time: 34 seconds, Memory: 438.50Mb
There were 50 errors:
1) XXXXXXXXXXX
PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(/usr/lib/php/pear/File/Iterator): failed to open dir: Too many open files' in /usr/lib/php/pear/File/Iterator/Factory.php:114
这可能是对运行代码的服务器的限制。每个操作系统只允许一定数量的打开文件/句柄/套接字。当服务器被虚拟化时,这个限制通常会进一步降低。在Linux服务器上,您可以使用ulimit -n
检查当前限制,如果您具有root访问权限,则可以使用相同的命令增加限制。我想Windows服务器也有一种方法。否则,你对此无能为力(除了要求你的房东或管理员增加它)。
更多可配置限制:
/etc/security/limits.conf
的变化
soft nofile 1024
hard nofile 65535
将ulimit增加ulimit -n 65535
或echo 65535 > /proc/sys/fs/file-max
或在/etc/sysctl.conf
:中
fs.file-max=65535
如何提高文件打开限制(Linux或Max OS):
ulimit -n 10000
解决了phpunit
或/和phpdbg
和Warning: Uncaught ErrorException: require([..file]): failed to open stream: Too many open files in [...]
的问题
在php中,在执行之前,请尝试此
exec('ulimit -S -n 2048');
从睡眠模式"唤醒"我的电脑后,我遇到了这个问题。
重新启动php-fpm像这样修复了它。经典关闭它&重复使用解决方案。
sudo /etc/init.d/php-fpm restart
我认为这可能与我最近添加到php中的xdebug有关。
以后不要存储DirectoryTerator对象;当您存储的文件超过操作系统限制(通常为256或1024)时,会出现一个错误,称为"打开的文件太多"。
例如,如果目录中的文件太多,这将产生错误:
<?php
$files = array();
foreach (new DirectoryIterator('myDir') as $file) {
$files[] = $file;
}
?>
据推测,这种方法也是内存密集型的。
来源:http://php.net/manual/pt_BR/directoryiterator.construct.php#87425
我注意到,在PHP中,当您忘记在闭包中包装某些内容时,会发生这种情况。仔细查看您最近的diff,您可能会了解到这一点(在我的案例中,我在Laravel PHP单元工厂中引用了$faker
,而没有关闭。
我在Http池中遇到了这个错误,我在池中添加了太多URL(大约2000个URL)。
我不得不把url分成更小的批,错误就停止了。
我认为这就是Guzzle Pool的工作原理,它不会在整个游泳池完成之前关闭卷曲连接。
示例
$responses = Http::pool(function (Pool $pool) use ($chunk) {
return collect($chunk)->map(fn($url) => $pool->get($url));
});
成为:
collect($urls)
->chunk(25)
->each(function ($chunk) {
$responses = Http::pool(function (Pool $pool) use ($chunk) {
return collect($chunk)->map(fn($url) => $pool->get($url));
});
});
Http函数是Laravel使用GuzzleHttpClient的包装函数。https://laravel.com/docs/9.x/http-client
在服务器debian上,您也可以转到
/etc/php/php7.xx/fpm/pool.d/www.conf
rlimit_files=10000
/etc/init.d/php7.xx restart
也许,文件/etc/init.d/phpx.x-fpm
有一些错误。让我们重新启动它:
sudo /etc/init.d/php7.2-fpm restart
每次Redis库PHP试图加载时,我都会遇到这个错误,但这是由我最初没有真正想到的事情引起的。当我的程序运行了一段时间,做了一个重复的过程时,我不断地得到这个错误。我发现我打开了一个cURL会话($ch = new curl_init(...)
),它在类的析构函数中被关闭,但该析构函数从未被调用。我解决了这个问题,打开太多文件的错误消失了。