1

I have to do a lot of processing in the server end, but don't want user to aware of it. I want to send user a response immediately and then run the process in the server end.

I've done some study, and so far I've done this:

function process(){
    ignore_user_abort(true);
    set_time_limit(0);

    ob_start();
    // Send response to the user
    header('Connection: close');
    header('Content-Length: '.ob_get_length());
    ob_end_flush();
    ob_flush();
    flush();

    // Post process

}

As far as I'm aware of, this should return the user response immediately and then run the post processes. But it's not working: it still waits until all the processes are done.

Bytheway, I'm sending an AJAX request if it helps. At first I thought it might be a problem with session locking, but now I'm not even using any session (session_status() returns 1).

PHP version is 7.1

NOTE: I've read other related questions where the above method works fine, but for some reason it's not working in my case.

Muntashir Akon
  • 8,740
  • 2
  • 27
  • 38
  • 1
    a better design would be to hand off this offline data-crunching to another process, e.g. a script triggered at regular intervals by a cron job. Your user-facing script would just write the details of the task and any necessary data into a DB table, for example, and the cron job script would look for new tasks in the table, and run them using the information provided. That way there's no dependency at all on the UI. – ADyson Sep 13 '17 at 15:15
  • @ADyson Thanks for the info. The above function should have worked though. But since using a Cron Job requires some major modification to the DB (which is a pain to me as I'm doing this project for free), I'll wait for a solution. But if I don't get a solution, I'll have no choice but endure the pain. – Muntashir Akon Sep 13 '17 at 15:28
  • 1
    As far as I'm aware output flushing doesn't work with ajax. The callback you've set for handling the response will only run when it sees the response is complete. It can't run repeatedly every time it gets a partial response (don't forget even though you've sent all the output you're going to send, until the PHP script completes it doesn't send a final response to the client) - you'd have to write the callback code quite differently to cope with that, and I've never seen an implementation of such a thing. – ADyson Sep 13 '17 at 20:11
  • 1
    Anyway, a redesign to use a background scheduled batch processor will probably be of benefit in the longer term too, especially if you make it a bit generic and potentially re-usable in other projects, or in this project if you have other tasks you need to run in the same sort of way. There might even be such a thing out there available as a free module if you google around - it's a fairly common requirement. – ADyson Sep 13 '17 at 20:12
  • @ADyson, you're right. [This answer](https://stackoverflow.com/a/9152562/4147849) seem to suggest an workaround, but it doesn't do much help to me. I think the best alternative way is the use of a Cron Job as you suggested earlier. – Muntashir Akon Sep 13 '17 at 20:45
  • It looks like neither AJAX request nor redirection works with this method. – Muntashir Akon Sep 14 '17 at 18:00

1 Answers1

1

It looks like (as @ADyson said in the comment) flushing output doesn't seem work with AJAX. So, the only solution to the problem is to use Cron Job. To do this, I used PHP Cron Scheduler. But crontab can be used directly to add a Cron Job to the list.

I added the post processes to another PHP file with suitable changes so that it can do the same tasks from the script and added the file to the Scheduler.

This solution may seem a real pain, but there is no solution to this problem other than using Cron Job.

Muntashir Akon
  • 8,740
  • 2
  • 27
  • 38