web-dev-qa-db-fra.com

Demande de curl asynchrone dans PHP

J'exécute deux demandes de publication curl en PHP. Voici à quoi ils ressemblent:

//Onfleet API credentials 
$username = 'xxxxx'; 
$api_onfleet = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';    
$url_onfleet = "https://onfleet.com/api/v2/tasks";

curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    $request =  $url.'api/mail.send.json';

    // Generate curl request
    $session = curl_init($request);
    // Tell curl to use HTTP POST
    curl_setopt ($session, CURLOPT_POST, true);
    // Tell curl that this is the body of the POST
    curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
    // Tell curl not to return headers, but do return the response
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);

    // obtain response
    $response = curl_exec($session);
    curl_close($session);


     // Post the Pickup task to Onfleet
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url_onfleet);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERPWD, $api_onfleet);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_ENCODING, "");  
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$pickup_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"completeBefore":'.$timestamp.',"pickupTask":"yes","autoAssign":{"mode":"distance"}}');

    $result_pickup = curl_exec($ch);
    curl_close($ch);

    // Post the Dropoff task to Onfleet
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url_onfleet);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_USERPWD, $api_onfleet);
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($curl, CURLOPT_ENCODING, "");  
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$dropoff_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"autoAssign":{"mode":"distance"}}');

    $result_dropoff = curl_exec($curl);
    curl_close($curl);

Ils fonctionnent, mais parfois, la deuxième demande de publication curl n'est pas exécutée.

Je voudrais exécuter ces deux demandes en même temps.

Comment puis je faire ça? Veuillez noter qu'ils prennent différentes options dans les post-champs.

Merci de votre aide!

12
Hyacinthe

Donc, ce que vous voulez faire, c'est l'exécution asynchrone des requêtes cUrl.

Vous auriez donc besoin d'une bibliothèque de traitement asynchrone/parallèle pour php.


pThreads

L'une des principales bibliothèques de threads pour php est pthreads

Vous devez d'abord obtenir le fichier dll/so et l'enregistrer dans le répertoire php/ext, Puis activer cette extension dans php.ini.

Après cela, ce code ferait votre travail:

class Request1 extends Thread {
    $username = 'xxxxx'; 
    $api_onfleet = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';    
    $url_onfleet = "https://onfleet.com/api/v2/tasks";
    public function run() {
        curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
        $request =  $this->url.'api/mail.send.json';

        // Generate curl request
        $session = curl_init($request);
        // Tell curl to use HTTP POST
        curl_setopt ($session, CURLOPT_POST, true);
       // Tell curl that this is the body of the POST
       curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
       // Tell curl not to return headers, but do return the response
       curl_setopt($session, CURLOPT_HEADER, false);
       curl_setopt($session, CURLOPT_RETURNTRANSFER, true);

        // obtain response
        $response = curl_exec($session);
        curl_close($session);
    }
}


class Request2 extends Thread {
    $username = 'xxxxx'; 
    $api_onfleet = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';    
    $url_onfleet = "https://onfleet.com/api/v2/tasks";
    public function run() {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url_onfleet);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      curl_setopt($ch, CURLOPT_USERPWD, $this->api_onfleet);
      curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
      curl_setopt($ch, CURLOPT_ENCODING, "");  
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$pickup_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"completeBefore":'.$timestamp.',"pickupTask":"yes","autoAssign":{"mode":"distance"}}');

      $result_pickup = curl_exec($ch);
      curl_close($ch);

      // Post the Dropoff task to Onfleet
      $curl = curl_init();
      curl_setopt($curl, CURLOPT_URL, $this->url_onfleet);
      curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
      curl_setopt($curl, CURLOPT_USERPWD, $this->api_onfleet);
      curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
      curl_setopt($curl, CURLOPT_ENCODING, "");  
      curl_setopt($curl, CURLOPT_POST, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$dropoff_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"autoAssign":{"mode":"distance"}}');

      $result_dropoff = curl_exec($curl);
      curl_close($curl);
    }
}

$req1 = new Request1();
$req1->start();
$req2 = new Request2();
$req2->start();

Donc, fondamentalement, vous devez créer une classe qui étend la classe Thread et tout ce que vous voulez exécuter de manière asynchrone (plutôt parallèle), serait placé dans la fonction run() de la classe.

Lorsque vous souhaitez démarrer le thread, instanciez simplement la classe dans une variable et appelez la méthode de démarrage de l'objet, comme $threadsObject->start() et tout dans la run() serait exécuté sur un autre thread.

Référence:

  1. class::Thread
  2. Thread::start

C'est ça.


Async cURL

L'autre façon est d'utiliser les fonctions intégrées fonctions cURL asynchrones .

Ainsi, lorsque vous utilisez curl_multi_*, Votre code ressemblerait à quelque chose comme:

$username = 'xxxxx'; 
$api_onfleet = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';    
$url_onfleet = "https://onfleet.com/api/v2/tasks";

curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    $request =  $url.'api/mail.send.json';

    // Generate curl request
    $session = curl_init($request);
    // Tell curl to use HTTP POST
    curl_setopt ($session, CURLOPT_POST, true);
    // Tell curl that this is the body of the POST
    curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
    // Tell curl not to return headers, but do return the response
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);


     // Post the Pickup task to Onfleet
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url_onfleet);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERPWD, $api_onfleet);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_ENCODING, "");  
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$pickup_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"completeBefore":'.$timestamp.',"pickupTask":"yes","autoAssign":{"mode":"distance"}}');
$mh = curl_multi_init();
curl_multi_add_handle($mh,$session);
curl_multi_add_handle($mh,$ch);

$active = null;
//execute the handles
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}
//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

Lecture suggérée:

  1. curl_multi_init()
  2. curl_multi_exec()
  3. curl_multi_add_handle()
  4. curl_multi_remove_handle()
35
Ikari