处理大卷曲响应 - PHP

Posted

技术标签:

【中文标题】处理大卷曲响应 - PHP【英文标题】:Dealing with large curl response - PHP 【发布时间】:2015-07-31 19:47:06 【问题描述】:

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

准备发布变量 初始化卷曲 设置客户端 cookie 以在请求中使用 将 POST 变量设置为查询字符串 设置其他卷曲选项 执行卷曲

代码如下:

    $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 以外的任何其他语言?

【问题讨论】:

您可以使用字节服务并仅请求整个文件的较小块,但是由于您随后将这些块加载到 DOM 中,因此无论如何您都需要整个文件。如果你输入一个不完整的文档,dom 会呕吐。 您要求什么,可能超过 1GB 的大小? (确定 HTTP 是正确的协议吗?) 我正在寻找 Web 服务中的安全漏洞并发现了一个通过 HTTP POST 泄露分析数据的漏洞,我只需将它们收集到 mysql 表中 【参考方案1】:

你可以做两件事:

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

What is the difference between SAX and DOM?

b) 使用 SAX 解析器时,使用 CURLOPT_WRITEFUNCTION 递增地传递数据.. 刚刚看到 lafor 也发布了这个,所以赞成

【讨论】:

【参考方案2】:

您可以使用带有回调的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
);

正如 cmets 中已经提到的,如果您的响应内容类型是您正在加载到 DOMDocument 中的 HTML,那么无论如何您首先需要完整的数据。

【讨论】:

以上是关于处理大卷曲响应 - PHP的主要内容,如果未能解决你的问题,请参考以下文章

卷曲响应无法理解

卷曲以返回 http 状态代码以及响应

sh 仅卷曲响应代码

php上传大文件时间大于http请求响应时间

使用 CURL 在 PHP 中集成 eWay 响应式共享页面

来自 curl php 的资源 id #2 响应