PHP中的异步curl请求

时间:2016-03-23 06:29:58

标签: php curl asynchronous request

我在PHP中执行两个curl post请求。这是他们的样子:

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

他们正在工作,但有时候,第二次卷曲请求不会被执行。

我想同时执行这两个请求。

我该怎么做?请注意,他们在后场采取不同的选择。

感谢您的帮助!

2 个答案:

答案 0 :(得分:33)

所以你想做的是异步执行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()中。

当你想要启动线程时,只需在变量中实例化类,并调用对象的start方法,如$threadsObject->start()run()中的所有内容都将在另一个线程上执行。< / p>

参考:

  1. class::Thread
  2. Thread::start
  3. 就是这样。

    异步cURL

    另一种方法是使用内置的asynchronous cURL functions

    因此,在使用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()

答案 1 :(得分:0)

签出此仓库asyncurl

此项目包含以下软件包: -异步 - 要求 -uvloop