36

我尝试在我的新机器上运行 PHPUnit 测试,但出现此错误:

PHP 致命错误:未捕获的异常 'UnexpectedValueException' 带有消息 'RecursiveDirectoryIterator::__construct(/usr/lib/php/pear/File/Iterator):无法打开目录:/usr/lib/php/pear 中打开的文件太多/文件/迭代器/Factory.php:114

旧机器上的相同代码运行良好......

新机环境: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
4

10 回答 10

50

这可能是对运行代码的服务器的限制。每个操作系统只允许一定数量的打开文件/句柄/套接字。当服务器被虚拟化时,这个限制通常会进一步降低。在 Linux 服务器上,您可以使用 来检查当前限制ulimit -n,如果您具有 root 访问权限,则可以使用相同的命令来增加它。我假设Windows服务器也有一种方法。否则,您无能为力(除了要求您的主机或管理员增加它)。

更多可配置的限制:

在某一方面的变化/etc/security/limits.conf

soft nofile 1024
hard nofile 65535

将 ulimit 增加ulimit -n 65535 orecho 65535 > /proc/sys/fs/file-max 或 in /etc/sysctl.conf

fs.file-max=65535
于 2013-02-07T10:39:32.630 回答
31

如何提高文件打开限制(Linux 或 Max OS):

ulimit -n 10000

解决phpunitor/and phpdbgand的问题Warning: Uncaught ErrorException: require([..file]): failed to open stream: Too many open files in [...]

于 2018-06-02T20:22:31.513 回答
5

在php中,在执行之前,试试这个

exec('ulimit -S -n 2048');
于 2016-12-13T13:29:36.843 回答
2

从睡眠模式“唤醒”我的电脑后,我遇到了这个问题。

像这样重新启动 php-fpm 修复它。经典将其关闭并重新打开解决方案。

sudo /etc/init.d/php-fpm restart

我认为这可能与我最近添加到 php.ini 中的 xdebug 有关。

于 2018-12-03T16:42:02.040 回答
1

不要为以后存储 DirectoryIterator 对象;当您存储超过操作系统限制(通常为 256 或 1024)时,您将收到“打开的文件过多”的错误消息。

例如,如果目录有太多文件,这将产生错误:

<?php 
$files = array(); 
foreach (new DirectoryIterator('myDir') as $file) { 
    $files[] = $file; 
} 
?>

据推测,这种方法也是内存密集型的。

来源: http: //php.net/manual/pt_BR/directoryiterator.construct.php#87425

于 2016-06-10T17:55:20.427 回答
1

当您忘记将某些内容包装在闭包中时,我注意到在 PHP 中会发生这种情况。仔细查看您最近的差异,您可能能够深入了解这一点(在我的情况下,我$faker在 Laravel PHP 单元工厂中引用而没有关闭。

于 2020-05-06T14:09:22.543 回答
1

在服务器 debian 上你也可以去

/etc/php/php7.xx/fpm/pool.d/www.conf

rlimit_files = 10000

/etc/init.d/php7.xx restart
于 2019-09-16T08:28:14.420 回答
0

我遇到了与 Http 池相关的错误,我在池中添加了太多 url(大约 2000 个 url)。

我不得不将网址分成更小的批次,并且错误停止了。

我认为它是 Guzzle Pool 的工作原理,它不会在整个池完成之前关闭 curl 连接。

前任。

$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 使用 Guzzle Http 客户端的包装函数。https://laravel.com/docs/9.x/http-client

于 2022-02-20T11:12:19.687 回答
0

每次 PHP 尝试加载 Redis 库时,我都会收到此错误,但它是由我一开始并没有真正想到的事情引起的。当我的程序运行一段时间时,我不断收到这个错误,做一个重复的过程。我发现我打开了一个 cURL 会话 ( $ch = new curl_init(...)),它在类的析构函数中关闭,但从未调用过该析构函数。我解决了这个问题,打开文件过多的错误消失了。

于 2021-01-31T02:03:29.483 回答
0

也许,您对 file 有一些错误/etc/init.d/phpx.x-fpm。让我们重新启动它:

sudo /etc/init.d/php7.2-fpm restart
于 2019-11-10T15:38:02.710 回答