Php 使用Symfony控制台时打开的文件过多,这是一个致命错误

Php 使用Symfony控制台时打开的文件过多,这是一个致命错误,php,symfony,laravel-4,Php,Symfony,Laravel 4,我正在运行一个控制台进程,该进程侦听事件并将写入控制台以指示进度。这可以运行10-15分钟,但大约10分钟后,我会遇到以下一系列严重的控制台错误: [2014-10-14 11:13:49] local.ERROR: 500 - fopen(php://stderr): failed to open stream: operation failed @ / exception 'ErrorException' with message 'fopen(php://stderr): failed t

我正在运行一个控制台进程,该进程侦听事件并将
写入控制台以指示进度。这可以运行10-15分钟,但大约10分钟后,我会遇到以下一系列严重的控制台错误:

[2014-10-14 11:13:49] local.ERROR: 500 - fopen(php://stderr): failed to open stream: operation failed @ /
exception 'ErrorException' with message 'fopen(php://stderr): failed to open stream: operation failed' in /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php:53
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleError(2, 'fopen(php://std...', '/vagrant/www/te...', 53, Array)
#1 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php(53): fopen('php://stderr', 'w')
#2 /vagrant/www/test.dev/laravel/app/library/ecomevo/task/src/eComEvo/TaskRunner/Traits/Events.php(262): Symfony\Component\Console\Output\ConsoleOutput->__construct()
#3 [internal function]: eComEvo\TaskRunner\TaskRunner::eComEvo\TaskRunner\Traits\{closure}('.', 280, Array)
#4 /vagrant/www/test.dev/laravel/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(199): call_user_func_array(Object(Closure), Array)
#5 /vagrant/www/test.dev/laravel/app/library/ecomevo/task/vendor/illuminate/support/Illuminate/Support/Facades/Facade.php(211): Illuminate\Events\Dispatcher->fire('task.group.prog...', Array)
#6 /vagrant/www/test.dev/laravel/app/library/ecomevo/task/src/eComEvo/TaskRunner/Traits/Events.php(92): Illuminate\Support\Facades\Facade::__callStatic('fire', Array)
#7 /vagrant/www/test.dev/laravel/app/library/ecomevo/task/src/eComEvo/TaskRunner/Traits/Events.php(92): Illuminate\Support\Facades\Event::fire('task.group.prog...', Array)
#8 /vagrant/www/test.dev/laravel/app/library/ecomevo/task/src/eComEvo/TaskRunner/Traits/Events.php(205): eComEvo\TaskRunner\TaskRunner::event('progress', '.', 280, '423403-23463321-604...', 'event')
#9 /vagrant/www/test.dev/laravel/app/models/TaskRunner.php(280): eComEvo\TaskRunner\TaskRunner::progress('.', 280, '2423-521354...')
#10 /vagrant/www/test.dev/laravel/app/library/ecomevo/task/src/eComEvo/TaskRunner/Commands/TaskRunnerImportOrdersCommand.php(128): TaskRunner::import('15', NULL, Array, '16', '4')
#11 /vagrant/www/test.dev/laravel/vendor/laravel/framework/src/Illuminate/Console/Command.php(112): eComEvo\TaskRunner\Commands\TaskRunnerImportOrdersCommand->fire()
#12 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Command/Command.php(252): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 /vagrant/www/test.dev/laravel/vendor/laravel/framework/src/Illuminate/Console/Command.php(100): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(889): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(193): Symfony\Component\Console\Application->doRunCommand(Object(eComEvo\TaskRunner\Commands\TaskRunnerImportOrdersCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#16 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(124): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#17 /vagrant/www/test.dev/laravel/artisan(59): Symfony\Component\Console\Application->run()
#18 {main} [] []
[2014-10-14 11:13:50] local.ERROR: 500 - proc_open(): unable to create pipe Too many open files @ /
exception 'ErrorException' with message 'proc_open(): unable to create pipe Too many open files' in /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php:983
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleError(2, 'proc_open(): un...', '/vagrant/www/te...', 983, Array)
#1 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(983): proc_open('stty -a | grep ...', Array, NULL, NULL, NULL, Array)
#2 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(799): Symfony\Component\Console\Application->getSttyColumns()
#3 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(760): Symfony\Component\Console\Application->getTerminalDimensions()
#4 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(690): Symfony\Component\Console\Application->getTerminalWidth()
#5 /vagrant/www/test.dev/laravel/vendor/laravel/framework/src/Illuminate/Console/Application.php(201): Symfony\Component\Console\Application->renderException(Object(ErrorException), Object(Symfony\Component\Console\Output\StreamOutput))
#6 /vagrant/www/test.dev/laravel/vendor/symfony/console/Symfony/Component/Console/Application.php(131): Illuminate\Console\Application->renderException(Object(ErrorException), Object(Symfony\Component\Console\Output\StreamOutput))
#7 /vagrant/www/test.dev/laravel/artisan(59): Symfony\Component\Console\Application->run()
#8 {main} [] []
以下是10分钟后触发这些错误的代码:

static::listen(
    'progress',
    function ($indicator = '.', $line = null, $id = 0) {
        $output = new \Symfony\Component\Console\Output\ConsoleOutput();

        $extra = [];

        if (static::$debug > 2) {
            if (!empty($line) && $line !== true)
                $extra[] = "line=$line";

            if (!empty($id)) {
                if (is_array($id))
                    $id = implode(',', $id);

                if (!empty($id))
                    $extra[] = "ID=$id";
            }
        }

        if (!empty($extra))
            $output->writeln('[' . implode(', ', $extra) . ']');
        elseif ($line === true)
            $output->writeln("\n$indicator");
        else
            $output->write($indicator);

        static $gc_count = 0;

        $gc_count++;

        if ($gc_count > 25) {
            $gc_count = 0;

            gc_collect_cycles();
        }
    },
    'event'
);
我四处寻找解决方案,所以我添加了
gc\u collect\u cycles()
行,希望这会有所帮助,但并没有解决问题。

查看,it总是在做一个
fopen($outputStream,'w')
,但我找不到任何可以再次关闭它的地方。
因此,您可以在函数结束时尝试自己关闭它:

$resource = $output->getStream();
fclose($resource);
或者只尝试实例化一次,然后重用它

注意:事实上,如果不再引用匿名函数,我认为垃圾收集应该关闭它。我不知道static::listen方法在做什么,所以手动关闭它可能值得一试