【问题标题】:Parallel cURL Request with WRITEFUNCTION Callback带有 WRITEFUNCTION 回调的并行 cURL 请求
【发布时间】:2013-04-01 03:18:59
【问题描述】:

我正在尝试按照以下帖子中的建议限制我的 cURL 响应:Retrieve partial web pagePHP CURLOPT_WRITEFUNCTION doesn't appear to be working。想法是将响应限制为回调函数中指定的 4000 个字符。

我编写了以下函数,但我已经知道它没有意义,因为回调函数定义中的参数在循环中不会像在函数调用中那样变化。在实际调用函数时,$key 的值是固定的,所以我对该索引的引用不会改变。

似乎每个循环都需要一个新的闭包函数,每个循环都需要引用自己的 $full_length 变量。但是,我不明白这怎么可能。为了做到这一点,似乎我必须以某种方式引用闭包对象才能指定特定的 $full_length 变量。

任何帮助将不胜感激。谢谢。

function get_headers($urls){
    $curly = array();
    $result = array();
    $mh = curl_multi_init();
    $obj = $this;
    foreach ($urls as $key => $url) {
        $this->full_length[$key] = 0;
        $callback = function ($ch, $string) use ($obj, $key){
                    $length = strlen($string);
                    $obj->full_length[$key] += $length;
                    if($obj->full_length[$key] >= 4000){
                        return -1;
                    }
                    return $length;
                };
        $curly[$key] = curl_init
        curl_setopt($curly[$key], CURLOPT_URL,            $url);
        curl_setopt($curly[$key], CURLOPT_HEADER,         0);
        curl_setopt($curly[$key], CURLOPT_WRITEFUNCTION, $callback);
        curl_setopt($curly[$key], CURLOPT_RETURNTRANSFER, 1);
        curl_multi_add_handle($mh, $curly[$key]);
    }
    $running = null;
    do {
        curl_multi_exec($mh, $running);
    } while($running > 0);
    foreach($curly as $key => $cnt) {
        $content = curl_multi_getcontent($cnt);
        curl_multi_remove_handle($mh, $cnt);
        if (strlen($content) > 0){
            $result[$key] = $content;
        } else {
            curl_multi_close($mh);
            return FALSE;
        }
    }
    curl_multi_close($mh);
    return $result;
}

编辑:

我发现一个帖子完全符合我的要求,但它是用 javascript 编写的: closure inside a for loop - callback with loop variable as parameter 。我编写了以下函数来尝试在 PHP 中做同样的事情:

function get_write_function($key){
    $this->full_length[$key] = 0;
    $obj = $this;
    $funky = function ($ch, $str) use ($obj, $key){
        $length = strlen($str);
        $obj->full_length[$key] += $length;
        if($obj->full_length[$key] >= 4000){
            return -1;
        }
        return $length;
    };
    return $funky;
}

代码运行没有错误,但仍然没有达到我想要的效果。关闭我的 cURL 句柄后,我转储了 $full_length 数组,它只显示:

array([0] => 0, [1] => 0)

这表明它们是由 get_write_function 初始化的(因为我没有在类声明中初始化任何东西),但是这些值之后从未更新过。

【问题讨论】:

    标签: php curl php-closures


    【解决方案1】:

    我终于明白了。最大的问题是 cURL 忽略了 WRITEFUNCTION 直到我将它作为指定的最后一个选项,正如我在此处发布的那样:cURL WRITEFUNCTION not Being Called。我实际上不需要返回传输,因为我将输出写入类变量。这是必要的,因为当回调返回 -1 时,不会返回任何内容。以下代码效果很好:

    var $full_length = array();
    var $result = array();
    
    function get_headers($urls){
        $curly = array();
        $mh = curl_multi_init();
        foreach ($urls as $key => $url) {
            $callback = $this->get_write_function($key);
            $curly[$key] = curl_init
            curl_setopt($curly[$key], CURLOPT_URL,            $url);
            curl_setopt($curly[$key], CURLOPT_HEADER,         0);
            curl_setopt($curly[$key], CURLOPT_WRITEFUNCTION, $callback);
            curl_multi_add_handle($mh, $curly[$key]);
        }
        $running = null;
        do {
            curl_multi_exec($mh, $running);
        } while($running > 0);
        foreach($curly as $key => $cnt) {
            curl_multi_remove_handle($mh, $cnt);
        }
        curl_multi_close($mh);
        return $this->result;
    }
    
    function get_write_function($key){
        $this->full_length[$key] = 0;
        $this->result[$key] = '';
        $obj = $this;
        $funky = function ($ch, $str) use ($obj, $key){
            $obj->result[$key] .= $str;
            $length = strlen($str);
            $obj->full_length[$key] += $length;
            if($obj->full_length[$key] >= 4000){
                return -1;
            }
            return $length;
        };
        return $funky;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-24
      • 2011-07-03
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多