Running an asynchronous PHP task using the Symfony Process

For time-consuming tasks (sending emails, image processing ... you understand), I want to run asynchronous PHP tasks.

pretty easy on Linux , but I'm looking for a method that works with Windows as well.

I want it to be as simple as it should be. No artillery , no SQL queues, setting stuff over and over ... I just want to run a damn asynchronous task.

So, I tried Symfony Process Component . The problem is that the execution of the task synchronously works fine, but when it is run asynchronously, it exits from the main script.

Is there any way to fix this?


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)); } 

result

 script (A) : 02:36:10 491 script (B) : 02:36:10 511 subscript (A) : 02:36:10 581 // subscript (B) is missing 
+5
source share
3 answers

The main script should wait for the async process to complete. Try this code:

 $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()); } 
+3
source

Not the best solution, but:

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

If php supports fpm for Windows , you can listen to the kernel.terminate event to provide all the expensive tasks after sending a response.

Services:

 app.some_listener: class: SomeBundle\EventListener\SomeListener tags: - { name: kernel.event_listener, event: kernel.terminate, method: onKernelTerminate } 

LISTENER:

 <?php namespace SomeBundle\EventListener; use Symfony\Component\HttpKernel\Event\PostResponseEvent; class SomeListener { public function onKernelTerminate(PostResponseEvent $event) { // provide time consuming tasks here } } 
0
source

Source: https://habr.com/ru/post/1215961/


All Articles