Php 使用Symfony控制台(CTRL+;C)捕捉终端终端/出口

Php 使用Symfony控制台(CTRL+;C)捕捉终端终端/出口,php,symfony,symfony-console,symfony-eventdispatcher,Php,Symfony,Symfony Console,Symfony Eventdispatcher,我已经创建了一个命令,可以通过internet触发文件下载,但是由于这些文件需要由另一个组件处理,我们需要确保在过去10秒内下载且未修改的每个文件都是正确的视频,并且未损坏/部分下载 出于这个原因,我们需要找到一种方法来捕获CTRL+C或命令终止,并清理任何尚未成功下载的适用文件 这就是迄今为止我使用symfony/console和symfony/event dispatcher尝试的方法: #!/usr/bin/env php <?php require_once(__DIR__ .

我已经创建了一个命令,可以通过internet触发文件下载,但是由于这些文件需要由另一个组件处理,我们需要确保在过去10秒内下载且未修改的每个文件都是正确的视频,并且未损坏/部分下载

出于这个原因,我们需要找到一种方法来捕获CTRL+C或命令终止,并清理任何尚未成功下载的适用文件

这就是迄今为止我使用
symfony/console
symfony/event dispatcher
尝试的方法:

#!/usr/bin/env php
<?php

require_once(__DIR__ . '/../vendor/autoload.php');

use Symfony\Component\Console\Application;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;
use ImportExport\Console\ImportCommand;
use Monolog\Logger;

$dotenv = new Dotenv\Dotenv(__DIR__ . '/../');
$dotenv->load();

$logger = new Logger('console');

$dispatcher = new EventDispatcher();
$dispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) {
    // gets the command that has been executed
    $command = $event->getCommand();

    var_dump($command);
});

$application = new Application("Import-Export System", 'v0.1.0-ALPHA');
$application->add(new ImportCommand($logger));
$application->setDispatcher($dispatcher);
$application->run();
#/usr/bin/env-php

当您执行CTRL+C时,实际上发送的是
SIGINT
,而不是
SIGTERM
。我能想到的最好的方法是注册处理程序,并使用pcntl\u signal\u dispatch发送信号,例如:

pcntl_signal(SIGINT,'sigIntHandler');

function sigIntHandler() {
  // Do some stuff
}
当然,你需要根据自己的需要进行调整。请注意,您还可以遵从命令中的类方法,例如,您可以使用generic
sigIntHandler()
创建一个AbstractCommand,并将其注册到构造函数中:

pcntl_signal(SIGINT, [$this, 'sigIntHandler']);

然后使用
pcntl\u signal\u dispatch()
例如在命令的循环中(需要在每次迭代中调用它)。

您可能想检查这个问题,但这也阻止了我实际使用CTRL+C。即使我中断了该命令,它仍会继续运行。它是一个处理程序,因此它实际上应该以您想要的方式处理信号。如果您想做一些事情,然后仍然停止执行,您可以使用
exit()
die()
函数。
pcntl\u signal\u dispatch()
需要在每个“任务”之后运行,以触发信号处理程序,这意味着如果发送SIGINT命令,则在运行
pcntl\u signal\u dispatch()
之前,不会执行处理程序。这意味着我不能在某件事情的中间中断某个进程。这取决于您在任务中执行的操作,但是如果您的操作阻止IO,那么您当然需要等待任务完成,然后再调用处理程序。