处理大卷曲响应 - PHP

时间:2015-05-19 19:46:53

标签: php curl

我编写了一个使用curl发出HTTP POST请求的PHP脚本,并执行以下操作,

  • 准备岗位变量
  • 初始化卷曲
  • 将客户端Cookie设置为在请求中使用
  • 将POST变量设置为查询字符串
  • 设置其他卷曲选项
  • 执行curl

以下是代码:

    $ch = curl_init ( $url );

    curl_setopt ( $ch, CURLOPT_COOKIE, "cookie=cookie");
    curl_setopt ( $ch, CURLOPT_POST, 1);
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_string);
    curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt ( $ch, CURLOPT_HEADER, 0);
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1);

    $response = curl_exec( $ch );
    // this point
    extr ( $response, $param_1, $param_2);

问题是,有时响应大于1GB,因此PHP代码暂停,直到收到完整响应(在代码中显示为// this point),如果HTML接收格式错误,PHP会生成错误,因此,这一切都需要从头开始。

以下是其余功能:

function extr($string = '',$a,$b)
{
    $doc = new DOMDocument;
    @$doc -> loadHTML($string);
    $table = $doc -> getElementById('myTableId');

    if(is_object($table)):
    foreach ($table->getElementsByTagName('tr') as $record)
    {
        $rec = array();
        foreach ($record->getElementsByTagName('td') as $data)
        {
            $rec[] = $data -> nodeValue;
        }
        if ($rec)
        {
            put_data($rec);
        }
    }
    else:
    {
        echo 'Skipped: Param1:'.$a.'-- Param2: '.$b.'<br>';
    }
    endif;
}

function put_data($one = array())
{
    $one = json_encode($one) . "\n";
    file_put_contents("data.json", $one, FILE_APPEND);
}

ini_set('max_execution_time', 3000000);
ini_set('memory_limit', '-1');

我能想到的另一种选择是过程数据,如果可能的话,使用curl,或继续之前状态的先前curl请求。

这有可能的解决方法吗?

我是否需要切换到PHP以外的任何其他语言?

2 个答案:

答案 0 :(得分:3)

您可以使用带有回调的CURLOPT_WRITEFUNCTION选项以块的形式处理数据:

curl_setopt($ch, CURLOPT_WRITEFUNCTION, function(&$ch, $data) {
   echo "\n\nchunk received:\n", $data; // process your chunk here
   return strlen($data); // returning non-positive number aborts further transfer
});

正如评论中已经提到的,如果您的回复内容类型是您正在加载到DOMDocument中的HTML,那么您无论如何都需要首先获得完整数据。

答案 1 :(得分:1)

你可以做两件事:

a)使用SAX解析器。 Sax解析器就像一个DOM解析器,但它可以处理DOM解析器必须拥有整个文档的流输入,否则会抛出错误。 Sax解析器只会为您提供要处理的事件。

What is the difference between SAX and DOM?

b)使用SAX解析器时,使用CURLOPT_WRITEFUNCTION以递增方式传递数据..只是看到lafor也发布了这个,所以upvoting