How can I run an fql request in the background? (a

2019-03-21 20:20发布

问题:

I'd like to run a particularly expensive fql query in the background, log results to the database, and retrieve it later without the user having to wait for each step.

Can you share an example of how to run a facebook request asynchronously?

main.php

$uid = $facebook->getUser();
if ($uid) {
    try {
        echo $user;

        ////////////////////////////////////////////////////////
        // Run lengthy query here, asynchronously (async.php) //
        ////////////////////////////////////////////////////////
        //                                                    //
        // For example: $profile = $facebook->api('/me');     //
        // (I know this request doesn't take long, but        //
        // if I can run it in the background, it'll do.       //
        //                                                    //
        ////////////////////////////////////////////////////////


    } catch (FacebookApiException $e) {
        echo $e;
    }
}

async.php

$profile = $facebook->api('/me');
$run = mysql_query("INSERT INTO table (id) VALUES (" . $profile['id'] . ");";

complete.php

echo getProfileId(); // assume function grabs id from db, as stored via async.php

回答1:

My solution to running PHP jobs in the background is just to have the script itself make a new request which executes the actual job.

The code I've used before is the following, I'm not sure if there are more elegant solutions... but it has worked more than well enough for me in the past. The reason I use fsock and not file_get_contents() etc is of course so that I won't have to wait for the job to finish (which would defeat the purpose)

$sock = fsockopen("127.0.0.1", 80);
fwrite($sock, "GET /yourjoburl/ HTTP/1.1\r\n");
fwrite($sock, "Host: yourdomain.com\r\n");
fwrite($sock, "Connection: close\r\n");
fwrite($sock, "\r\n");
fflush($sock);
fclose($sock);

So, then you just have the other script write the results and progress to a database or whatever... also remember that MySQL supports mutexes, which means you can easily prevent multiple jobs from running at the same time... or to allow other scripts to wait for the job to finish.

PS. The reason I personally avoid exec and all that stuff is that it just seems like a hassle to work with, different servers, different setups, different OSes, etc. This works the same on all hosts that allow you to open sockets. Although you might want to add a private key to the request that you verify in the job, or check the IP of the caller, to prevent others from being able to start jobs.

EDIT: This is untested but should work if you want to forward the cookies as well, including the session cookie.

$sock = fsockopen("127.0.0.1", 80);
fwrite($sock, "GET /yourjoburl/ HTTP/1.1\r\n");
fwrite($sock, "Host: yourdomain.com\r\n");
fwrite($sock, "Cookie: " . $_SERVER['HTTP_COOKIE'] . "\r\n");
fwrite($sock, "Connection: close\r\n");
fwrite($sock, "\r\n");
fflush($sock);
fclose($sock);