简体   繁体   中英

Abandon Long Processes in PHP (But let them complete)

I have an HTML form that submits to a PHP page which initiates a script. The script can take anywhere from 3 seconds to 30 seconds to run - the user doesn't need to be around for this script to complete.

Is it possible to initiate a PHP script, immediately print "Thanks" to the user (or whatever) and let them go on their merry way while your script continues to work?

In my particular case, I am sending form-data to a php script that then posts the data to numerous other locations. Waiting for all of the posts to succeed is not in my interest at the moment. I would just like to let the script run, allow the user to go and do whatever else they like, and that's it.

Place your long term work in another php script, for example

background.php:

sleep(10);
file_put_contents('foo.txt',mktime());

foreground.php

$unused_but_required = array();
proc_close(proc_open ("php background.php &", array(), $unused_but_required));
echo("Done);

You'll see "Done" immediately, and the file will get written 10 seconds later.

I think proc_close works because we've giving proc_open no pipes, and no file descriptors.

In the script you can set:

<?php
 ignore_user_abort(true);

That way the script will not terminate when the user leaves the page. However be very carefull when combining this whith

 set_time_limit(0);

Since then the script could execute forever.

You can use set_time_limit and ignore_user_abort , but generally speaking, I would recommend that you put the job in a queue and use an asynchronous script to process it. It's a much simpler and durable design.

You could try the flush and related output buffer functions to immediately send the whatever is in the buffer to the browser:

Theres an API wrapper around pcntl_fork() called php_fork .

But also, this question was on the Daily WTF ... don't pound a nail with a glass bottle.

I ended up with the following.

<?php

  // Ignore User-Requests to Abort
  ignore_user_abort(true);
  // Maximum Execution Time In Seconds
  set_time_limit(30);

  header("Content-Length: 0");
  flush();

  /*

    Loooooooong process

  */

?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM