Запрос асинхронного завитка в PHP

Я выполняю два запроса на curl post в PHP. Вот как они выглядят так:

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

Они работают, но иногда второй запрос на откат не выполняется.

Я хотел бы выполнить эти два запроса одновременно.

Как я могу это сделать? Обратите внимание, что они принимают разные варианты в полях.

Спасибо за вашу помощь!

Ответ 1

Итак, что вы хотите сделать, это асинхронное выполнение запросов cUrl.

Таким образом, вам понадобится библиотека асинхронной/параллельной обработки для php.


PThreads

Одна из известных библиотек потоков для php - pthreads

Вам нужно будет сначала получить файл dll/so и сохранить его в php/ext и включить это расширение в php.ini.

После этого этот код выполнит вашу работу:

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

Итак, в основном вам нужно создать класс, который расширяет класс Thread и все, что вы хотите запустить асинхронно (скорее параллельно), будет помещено в функцию run() класса.

Когда вы хотите запустить поток, просто создайте экземпляр класса в переменной и вызовите метод запуска объекта, например $threadsObject->start() и все в run() будет выполнено в другом потоке.

Справка:

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

Это.


Async cURL

Другой способ - использовать встроенные асинхронные функции cURL.

Таким образом, при использовании curl_multi_* ваш код будет выглядеть примерно так:

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

Предлагаемое чтение:

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

Ответ 2

оформить заказ в этом репо asyncurl

Этот проект состоит из следующих пакетов: - asyncio - запросы - uvloop