0

I am building a WebService, using PHP:

Basically,

  1. User sends a request to the server, via HTTP Request. 'request.php', ie.
  2. Server starts php code asynchronously. 'update.php', ie.
  3. The connection with the user is finished.
  4. The code 'update.php' is still running, and will finish after some time.
  5. The code 'update.php' is finished.

The problem is with php running asynchronously some external code.

Is that possible? Is there another way to do it? With shell_exec?

Please, I need insights! An elegant way is preferable.

Thank you!

1
  • 1
    you can fork off a process, exec() an external program and put it in the background, or just have ignore_user_abort() at some level. Commented Feb 28, 2014 at 17:58

4 Answers 4

2

The best approach is using message queue like RabbitMQ or even simple MySQL table.

Each time you add new task in front controller it goes to queue. Then update.php run by cron job fetch it from queue, process, save results and mark task as finished.

Also it will help you distribute load over time preventing from DoS caused by your own script.

Sign up to request clarification or add additional context in comments.

1 Comment

Be sure to implement some logic to check if jobs are already running, you don't want to keep firing up new jobs before the old one finish and bogging down your server.
1

You could have the user connect to update.php, generate some sort of unique ID to keep track of the process, and then call fsockopen() on itself with a special GET variable to signify that it's doing the heavy lifting rather than user interaction. Close that connection immediately, and then print out the appropriate response to the user.

Meanwhile, look for the special GET variable you specified, and when present call ignore_user_abort() and proceed with whatever operations you need in that branch of the if clause. So here's a rough skeleton of what your update.php file would look like:

<?php

if ( isset($_GET['asynch']) ) {

    ignore_user_abort();

    // check for $_GET['id'] and validate,
    // then execute long-running code here

} else {

    // generate $id here

    $host = $_SERVER['SERVER_NAME'];
    $url = "/update.php?asynch&id={$id}";

    if ( $handle = fsockopen($host, 80, $n, $s, 5) ) {
        $data = "GET {$url} HTTP/1.0\r\nHost: {$host}\r\n\r\n";
        fwrite($handle, $data);
        fclose($handle);
    }

    // return a response to the user
    echo 'Response goes here';

}

?>

Comments

1

You could build a service with PHP. Or launch a PHP script using bash : system("php myScript.php param param2 &")

3 Comments

the & at the end of the command means to launch this in a separate thread so your php script shouldn't hang.
+1 for UNIX solution. But I was searching for a cross-OS solution.
Then use this one : For the usage of php as a service, I had a similar experience where I had to send SMS, users would upload a csv file : phone_number;text_message; I would launch the script once, and in a while 1 loop, beginning with a sleep(n) I would check the directory for any file, and if any, read the tenth first lines, remove them from the file, and send the ten sms.
0

Look into worker processes with Redis resque or gearman

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.