php - 使 curl_multi 'sleep' 或等待发送下一个请求

标签 php curl asynchronous

我正在使用 curl_multi 发出异步请求:http://php.net/manual/en/function.curl-multi-init.php

脚本向所有给定的 URL 发送请求,这对于我正在做的事情来说有点快。有没有办法降低请求率?

最佳答案

function asyncCurl($url){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
  curl_setopt($ch, CURLOPT_TIMEOUT, 1);
  curl_exec($ch);
  curl_close($ch);
}

$timeout = 3; // in seconds
$urls = array(...);

foreach($urls as $url){
  asyncCurl($url);
  sleep($timeout);
}

如果您需要获得响应,仍然可以通过在您的服务器上创建“后台进程”类型的东西来完成。这将需要 2 个脚本而不是一个。

background.php

function curl($url){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  $a = curl_exec($ch);
  curl_close($ch);
  return $a;
}

$response = curl($_GET['url']);

// code here to handle the response

doRequest.php(或其他任何内容,这是您将在浏览器中调用的文件)

function asyncCurl($url){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "mydomain.com/background.php?url=".urlencode($url));
  curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
  curl_setopt($ch, CURLOPT_TIMEOUT, 1);
  curl_exec($ch);
  curl_close($ch);
}

$timeout = 3; // in seconds
$urls = array(...);

foreach($urls as $url){
  asyncCurl($url);
  sleep($timeout);
}

这里的想法是 PHP 是单线程的,但没有理由不能让多个 PHP 进程同时运行。唯一的缺点是您必须在一个脚本上发出请求并在另一个脚本上处理响应。


选项 3:输出可用时立即显示。

这个方法和上面的完全一样,只不过是用javascript创建了一个新的php进程。您没有标记 javascript,但这是完成两者的唯一方法

  • 带超时的异步请求

  • 响应可用时立即显示响应

    doRequest.php

    <?php
    
    $urls = array(); // fill with your urls
    $timeout = 3; // in seconds
    
    if (isset($_GET['url'])) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $_GET['url']);
        $a = curl_exec($ch);
        curl_close($ch);
        echo $a;
        exit;
    }
    
    ?><html>
    <body>
        <div id='results'></div>
        <script>
    
            var urls = <?php echo json_encode($urls); ?>;
            var currentIndex = 0;
    
            function doRequest(url) {
                var xhttp = new XMLHttpRequest();
                xhttp.onreadystatechange = function () {
                    if (xhttp.readyState == 4 && xhttp.status == 200) {
                        document.getElementById("results").insertAdjacentHTML("beforeend", "<hr>" + xhttp.responseText);
                    }
                };
                xhttp.open("GET", "doRequest.php?url=" + encodeURIComponent(url), true);
                xhttp.send();
            }
    
            var index=0;
            function startLoop(){
                var url = urls[index];
                doRequest(url);
                setTimeout(function(){
                    index++;
                    if('undefined' != urls[index]) startLoop();
                }, <?php echo $timeout*1000; ?>);
            }
    
            startLoop();
        </script>
    </body>
    

发生的事情是你的服务器正在为每个 url 创建一个新的请求,然后使用普通的 curl 来获取响应,但是我们没有使用 curl 来创建新进程,而是使用 ajax,它本质上是异步的并且能够创建多个 PHP 进程并等待响应。

祝一切顺利!

关于php - 使 curl_multi 'sleep' 或等待发送下一个请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34642620/

相关文章:

php - 在 PHP 中关闭外部连接(例如 memcached、redis)是一个好习惯吗?

php - 尽管对文件进行了更改,但 filemtime() 在执行期间保持不变

php - 将命令行curl转换为PHPcurl函数

javascript - 重写这个弗兰肯斯坦 promise 链

javascript - For 循环、异步等待、Promise - Javascript

php - 使用 imagick 使用 PHP 将 PDF 转换为 JPG 适用于平面 pdf,但在有多个图层时失败

php - Laravel,将JSON数组转换为Array,并且只从Array中获取一个对象

java - 获取错误 Fielddata 在 CURL 中默认在文本字段上被禁用

ssl - 引入 TCP ZeroWindow 后会发生什么?

c# - 这两种方法有什么区别?