PHP cURL 只需要发送,而不等待响应

2022-08-30 14:56:38

我需要一个PHP cURL配置,以便我的脚本能够发送请求并忽略API发送的答案。

curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
//curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100);
$result = curl_exec($ch);
echo $result;
curl_close ($ch);

我尝试添加: // curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100);

但它不能正常工作,API Web服务器没有收到请求。

这样做的原因是我向API发送了大量请求,因此我的脚本非常慢,因为它会等待每个请求。

任何帮助是值得赞赏的。


答案 1

发件人文件示例 ./ajax/sender.php

脚本发送POST ->它向主机发出完整的请求,但它不会等待来自服务器的应答:CURLOPT_HEADER(0)我们不需要来自服务器的标头)和CURLOPT_RETURNTRANSFER(false)我们不需要来自服务器的数据。CURLOPT_TIMEOUT - 额外的procteted:我们在响应服务器上只发送了1ms之后等待,如果服务器保留我们,这是额外的质量,不再等待任何ms。### 注意 ###HTTP1.1 有一个最大 16kb 的软件包。HTTP2有36kb一个pacakge。如果 POST 更大,则服务器将连续发送许多包 = $SIZE%16kb

    $url = 'https://127.0.0.1/ajax/received.php';
    $curl = curl_init();                
    $post['test'] = 'examples daata'; // our data todo in received
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt ($curl, CURLOPT_POST, TRUE);
    curl_setopt ($curl, CURLOPT_POSTFIELDS, $post); 
    
    curl_setopt($curl, CURLOPT_USERAGENT, 'api');

    //curl_setopt($curl, CURLOPT_TIMEOUT, 1); //if your connect is longer than 1s it lose data in POST better is finish script in recevie
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl,  CURLOPT_RETURNTRANSFER, false);
    curl_setopt($curl, CURLOPT_FORBID_REUSE, true);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 1);
    curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT, 100); 
    
    curl_setopt($curl, CURLOPT_FRESH_CONNECT, true);
    
    curl_exec($curl);   
    
    curl_close($curl);  

接收的文件示例 ./ajax/received.php

    ignore_user_abort(true); //if connect is close, we continue php script in background up to script will be end
    
            header("Connection: close\r\n"); 
            header("Content-Encoding: none\r\n"); 
            header("Content-Length: 1"); 
    ### we just close connect above if webbrowser, or request waiting on answer ( we know we set CURLOP to not wait) ###
ob_end_clean(); //just flush all content if exists to request. If server still waiting on answer.
            //HERE all script doing in background: Example
            $this->db->query('UPDATE new_hook_memory SET new=new+1 WHERE id=1');
 

编辑 2019 如果你使用 fastcgi 只是完成 fastcgi 和浏览器关闭连接,但脚本仍然会工作到最后。

如何完成脚本:PHP mod_fcgi与fastcgi_finish_request();

对于 Apache2:

ob_end_flush();
flush();

对于 php-fpm

fastcgi_finish_request(); $this->db->query('UPDATE new_hook_memory SET new=new+1 WHERE id=1');

旧版本:


答案 2

这两种解决方案对我来说效果很好

(当然已经很久了,但我不认为这个问题已经过时了)

使用file_get_contents

  //url of php to be called

$url = "example.php/test?id=1";

  //this will set the minimum time to wait before proceed to the next line to 1 second

$ctx = stream_context_create(['http'=> ['timeout' => 1]]);

file_get_contents($url,null,$ctx);

  //the php will read this after 1 second 

使用 cURL

  //url of php to be called

$url = "example.php/test?id=1";

$test = curl_init();

  //this will set the minimum time to wait before proceed to the next line to 100 milliseconds

curl_setopt_array($test,[CURLOPT_URL=>$url,CURLOPT_TIMEOUT_MS=>100,CURLOPT_RETURNTRANSFER=>TRUE]);

curl_exec($test);

  //this line will be executed after 100 milliseconds

curl_close ($test); 

在这两种情况下,被调用的 php 都必须设置 。ignore_user_abort(true)

并且在这两种情况下都不会打印结果,但要小心您将设置的超时,它需要大于被调用的php开始产生结果所需的时间。


推荐