使用Symfony Process运行asynchronousPHP任务

对于耗时的任务(电子邮件发送,image processing…你明白了),我想运行asynchronousPHP任务。

在Linux上这很容易 ,但我正在寻找一种在Windows上工作的方法。

我希望它是简单的,因为它应该是。 没有大炮 ,没有SQL排队,没有再次安装的东西 …我只想运行一个该死的asynchronous任务。

所以我尝试了Symfony过程组件 。 问题是,同步运行任务可以正常工作,但是当它asynchronous运行时,它会沿着主脚本退出。

有没有办法来解决这个问题?

composer require symfony/process 

的index.php

 <?php require './bootstrap.php'; $logFile = './log.txt'; file_put_contents($logFile, ''); append($logFile, 'script (A) : '.timestamp()); $process = new Process('php subscript.php'); $process->start(); // async, subscript exits prematurely… //$process->run(); // sync, works fine append($logFile, 'script (B) : '.timestamp()); 

subscript.php

 <?php require './bootstrap.php'; $logFile = './log.txt'; //ignore_user_abort(true); // doesn't solve issue… append($logFile, 'subscript (A) : '.timestamp()); sleep(2); append($logFile, 'subscript (B) : '.timestamp()); 

bootstrap.php中

 <?php require './vendor/autoload.php'; class_alias('Symfony\Component\Process\Process', 'Process'); function append($file, $content) { file_put_contents($file, $content."\n", FILE_APPEND); } function timestamp() { list($usec, $sec) = explode(' ', microtime()); return date('H:i:s', $sec) . ' ' . sprintf('%03d', floor($usec * 1000)); } 

结果

 script (A) : 02:36:10 491 script (B) : 02:36:10 511 subscript (A) : 02:36:10 581 // subscript (B) is missing 

Solutions Collecting From Web of "使用Symfony Process运行asynchronousPHP任务"

当异步进程完成时,主脚本必须等待。 试试这个代码:

 $process = new Process('php subscript.php'); $process->start(); do { $process->checkTimeout(); } while ($process->isRunning() && (sleep(1) !== false)); if (!$process->isSuccessful()) { throw new \Exception($process->getErrorOutput()); } 

不是最好的解决方案,但:

 $process = new Process('nohup php subscript.php &'); $process->start(); 

如果php支持Windows的fpm ,则可以在发送响应之后监听kernel.terminate事件以提供所有昂贵的任务。

服务:

 app.some_listener: class: SomeBundle\Eventlistner\Somelistner tags: - { name: kernel.event_listener, event: kernel.terminate, method: oncoreelTerminate } 

监听器:

 <?php namespace SomeBundle\Eventlistner; use Symfony\Component\Httpcoreel\Event\PostResponseEvent; class Somelistner { public function oncoreelTerminate(PostResponseEvent $event) { // provide time consuming tasks here } }