0

I have a webform that sends data to PHP script.

PHP script may take a while to process the data. What I want to do is to send raw data to database, then redirect the visitor to "thank you" page and then continue processing the data in background. Important thing is that the script must continue working even if the visitor closes "thank you" page.

Can you advise which solution should I look into?

P.S. I use nginx + php-fpm if that matters.

UPDATE. I've found info about using ignore_user_abort(true). Could this be the way to go?

Ubertone
  • 63
  • 7
  • AJAX might be a solution for you. – Jay Blanchard Oct 21 '14 at 12:22
  • http://stackoverflow.com/questions/45953/php-execute-a-background-process – sridesmet Oct 21 '14 at 12:23
  • Define "a while". Seconds? Minutes? Hours? Long enough that the user might close the browser and leave before it's done? – David Oct 21 '14 at 12:24
  • 2
    @JayBlanchard ajax would cause the request still to be handled synchronously at the server side, making the ajax request time out. Doing a background process or a cron job would be more feasible – DoXicK Oct 21 '14 at 12:24
  • [How to Run PHP Code in the background](http://www.sitecrafting.com/blog/to-run-php-code-in) might help. – scrappedcola Oct 21 '14 at 12:26
  • That's why I said "might" @DoXicK :) The problem here is that we don't know what processing is supposed to occur and why it "may take a while" to process. – Jay Blanchard Oct 21 '14 at 12:27
  • Fair point. I was assuming the background task takes longer than +-30 seconds. – DoXicK Oct 21 '14 at 12:28
  • It can take up to a minute because relies on connecting to external service API. – Ubertone Oct 21 '14 at 12:31

3 Answers3

3

What I want to do is to send raw data to database, then redirect the visitor to "thank you" page and then continue processing the data in background.

That basically describes how I'd do it right there, actually.

Consider two separate applications. One is the web application, which saves the user input to the database and then continues to interact with the user. The other is a scheduled console application (a standalone script invoked by cron most likely) which looks for data in the database to be processed and processes it.

The user uploads the data, receives a "thank you" message, and his/her interaction is complete. The next time the scheduled task runs (every couple minutes, maybe?) it sees the pending data in the database, flags it as being processed (so if another instance of the script runs it doesn't also try to process the same data), processes it, flags it as being done (so it doesn't pick it up again next time), and completes.

You can notify the user of the completed process a couple of different ways. The back-end script can send the user an email (active notification), or perhaps the web application can examine the table for the flagged completed records the next time the user visits the page (passive notification).

David
  • 208,112
  • 36
  • 198
  • 279
  • Thanks for the suggestion! I will think about this approach with cron. – Ubertone Oct 21 '14 at 12:36
  • 1
    One more thanks because this approach solves another problem - if the external API used in processing is unavailable for some reason, the cron job will keep trying to send the info every time it runs. Great solution! – Ubertone Oct 21 '14 at 12:40
  • @Ubertone: Depending on how the logic is set up, there's a lot you can do fairly easily by separating the concerns like this. As you say, an automatic re-try is a significant benefit. You can also mark specific records as "failed" and continue with the remaining records, so a user's data doesn't entirely fail processing just because of one bad record. And so on. – David Oct 21 '14 at 12:42
0

Something like this should work :

pclose(popen('php script.php &', 'r'));

http://fr2.php.net/manual/fr/function.popen.php

You can also use more options or others functions to get more control over the execution :

http://fr2.php.net/manual/fr/function.proc-open.php

But use this carefully and be sure you need this way to resolve your problem.

Ajax would be nice.

Kern
  • 858
  • 1
  • 8
  • 24
-1

You need to do the thing asynchronously. Use AJAX to achieve this

vsingh
  • 470
  • 4
  • 9
  • 2
    Ajax would still have the request be handled synchonously thus making the ajax request wait for the result. – DoXicK Oct 21 '14 at 12:25
  • This doesn't really explain much and kind of treats "AJAX" as sort of a magic wand. Probably better as a comment than an answer. – David Oct 21 '14 at 12:30
  • @DoXicK: You are correct technically. It actually depends what further process will be involved in this scenario. Don't understand why this answer is downvoted. – vsingh Oct 21 '14 at 12:31
  • @David Thanks for the insights about how to give depth to the answers..;) – vsingh Oct 21 '14 at 12:36
  • 1
    @vsingh: It was probably downvoted because it doesn't really answer the question. "Use AJAX" isn't an answer, and doesn't do much to address the question being asked. – David Oct 21 '14 at 12:37
  • 2
    i guess it got downvoted since it doesn't give an actual answer, like david already said. It's like saying: 'how do i get from A to B?' -> "walk". While by definition not a wrong answer, it's not usefull either :-) – DoXicK Oct 21 '14 at 12:47