2010-08-07 43 views
11

我使用PHP的cURL函数从steampowered.com读取配置文件。检索的数据是XML,只需要大约1000字节。无法限制PHP的cURL函数的下载大小

我正在使用的方法是添加一个Range标题,我在堆栈溢出答案(curl: How to limit size of GET?)上阅读。我尝试过的另一种方法是使用curlopt_range,但那也不起作用。

<? 
$curl_url = 'http://steamcommunity.com/id/edgen?xml=1'; 
$curl_handle = curl_init($curl_url); 

curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); 
curl_setopt ($curl_handle, CURLOPT_HTTPHEADER, array("Range: bytes=0-1000")); 

$data_string = curl_exec($curl_handle); 

echo $data_string; 

curl_close($curl_handle); 
?> 

当执行此代码时,它将返回整个事物。

我正在使用PHP版本5.2.14。

+3

你确定你要查询的服务器支持范围吗?因为当我从命令行尝试时,我也得到了整个文档,这导致我相信steamcommunity.com没有启用该功能 – Doon 2010-08-07 19:19:59

回答

18

服务器不遵守范围标题。您可以做的最好的办法是在您收到比您想要的更多数据时立即取消连接。例如:

<?php 
$curl_url = 'http://steamcommunity.com/id/edgen?xml=1'; 
$curl_handle = curl_init($curl_url); 

$data_string = ""; 
function write_function($handle, $data) { 
    global $data_string; 
    $data_string .= $data; 
    if (strlen($data_string) > 1000) { 
     return 0; 
    } 
    else 
     return strlen($data); 
} 

curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); 
curl_setopt ($curl_handle, CURLOPT_WRITEFUNCTION, 'write_function'); 

curl_exec($curl_handle); 

echo $data_string; 

也许更干净,你可以使用HTTP包装(这也将使用卷曲,如果它与--with-curlwrappers编译)。基本上,如果您获得的数据超过您的要求,您可以在循环中调用fread,然后在流上使用fclose。您也可以使用传输流(如果allow_url_fopen已禁用,则使用fsockopen而不是fopen打开流并手动发送标题)。

+0

这确实有效!虽然,我不完全理解CURLOPT_WRITEFUNCTION的机制。你能解释那里发生了什么?再次感谢。 – Curtis 2010-08-07 19:53:35

+1

@Cur每次接收到新数据时,它都会被curl扩展调用。回调接收curl处理程序和刚才读取的数据。它应该返回读取的字节数,如果没有,它会中止传输(虽然这最后一部分没有记录,它似乎是行为)。 – Artefacto 2010-08-07 20:01:41

+2

@Cur OK我在这里找到了文档:“返回实际处理的字节数,如果这个数量与传递给函数的数量不同,它会向库发出一个错误信号,这会中止传输并返回CURLE_WRITE_ERROR“。 http://curl.haxx.se/libcurl/c/curl_easy_setopt.html – Artefacto 2010-08-07 20:06:39