3 votes

Comment puis-je exécuter une requête fql en arrière-plan ? (appels api asynchrones via php)

J'aimerais exécuter une requête fql particulièrement coûteuse en arrière-plan, enregistrer les résultats dans la base de données et les récupérer ultérieurement sans que l'utilisateur doive attendre à chaque étape.

Pouvez-vous nous donner un exemple de l'exécution asynchrone d'une requête facebook ?

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'] . ");";

complet.php

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

2voto

Andreas Points 1240

Ma solution pour exécuter des tâches PHP en arrière-plan est simplement de faire en sorte que le script lui-même fasse une nouvelle requête qui exécute la tâche réelle.

Le code que j'ai utilisé auparavant est le suivant, je ne suis pas sûr qu'il existe des solutions plus élégantes... mais cela a fonctionné plus que bien pour moi dans le passé. La raison pour laquelle j'utilise fsock et non file_get_contents() etc. est bien sûr que je n'ai pas à attendre que le travail se termine (ce qui irait à l'encontre du but recherché).

$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);

Donc, ensuite, il suffit que l'autre script écrive les résultats et la progression dans une base de données ou autre... rappelez-vous également que MySQL supporte les mutex, ce qui signifie que vous pouvez facilement empêcher plusieurs travaux de s'exécuter en même temps... ou pour permettre aux autres script d'attendre que le travail se termine.

PS. La raison pour laquelle j'évite personnellement exec et tous ces trucs, c'est qu'il me semble que c'est un peu compliqué de travailler avec, différents serveurs, différentes configurations, différents OS, etc. Cela fonctionne de la même manière sur tous les hôtes qui vous permettent d'ouvrir des sockets. Bien que vous puissiez ajouter une clé privée à la requête que vous vérifiez dans le travail, ou vérifier l'IP de l'appelant, pour empêcher d'autres personnes de lancer des travaux.

EDIT : Cette méthode n'a pas été testée mais devrait fonctionner si vous souhaitez également transférer les cookies, y compris le cookie de session.

$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);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X