您好,匿名用户
随意问技术百科期待您的加入

php的curl如何使用head协议来获取资源的大小等信息

0 投票

我的程序里允许用户填写网址从其它网站抓取资源,但是在抓取之前我要知道资源的大小,要不然资源太大耗时太长也会占用不必要的带宽。我查到了http里面有HEAD这个协议,就是只获取一个资源的http头部信息,那么在curl里怎么只获取http的头而不下载全部body呢?

还有content-length是所有的http头部信息里必须都有的吗,因为我只有这个办法来获取资源大小了。如果没有这个信息,我想用一个替代方法,就是设置curl下载资源的最大长度,如果超过了就中断连接,然后报错。在curl有达到此类效果的选项吗?

最后问一点,各大服务器对HEAD协议支持情况如何呢?

用户头像 提问 2012年 12月1日 @ Kog'Maw 上等兵 (212 威望)
分享到:

1个回答

0 投票
 
最佳答案

其实curl里面早就有对HEAD协议的支持

// 只需要在你的代码中加上这样一行,就会自动选择head协议
curl_setopt($ch, CURLOPT_NOBODY, true);

如果你要读取Content-Length,那么只需要在curl_exec

// 读取的header里的Content-Length值
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);

需要说明的是HEAD协议虽然被大部分服务器支持,但也不是说所有的服务器都支持,有的服务器为了防抓取,在设置中干掉了这个协议。而Content-Length也不是必须的字段,你应该做到如果有这个值,而且超过了最大值,可以返回错误,如果没有这个值,或者没有超过最大值,就必须自己通过已经下载的内容大小来判断。

至于你说的最大资源下载长度,我还没看到这个设置项,不过这个问题有一个更加美好的解决方案,那就是用到CURLOPT_HEADERFUNCTIONCURLOPT_WRITEFUNCTION两个回调,那么就只需要一次请求即可完成所有的判断,而且可以随时断掉

$size = 0;
$max_size = 123456;

curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $str) {
	// 第一个参数是curl资源,第二个参数是每一行独立的header!
    list ($name, $value) = array_map('trim', explode(':', $str, 2));
    $name = strtolower($name);
    
    // 判断大小啦
    if ('content-length' == $name) {
    	if ($value > $max_size) {
        	return 0;	// 返回0就会中断读取
        }
    }
});

// 对于没有content-length的,我们一边读取一边判断
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $str) use (&$size) {
	$len = strlen($str);
    $size += $len;
    
    if ($size > $max_size) {
    	return 0;	// 中断读取
    }
    
    return $len;
});
用户头像 回复 2012年 12月1日 @ Virgo 上等兵 (284 威望)
选中 2012年 12月1日 @Kog'Maw
提一个问题:

相关问题

0 投票
1 回复 41 阅读
用户头像 提问 2012年 12月1日 @ Ziggs 上等兵 (345 威望)
0 投票
1 回复 50 阅读
用户头像 提问 2012年 12月1日 @ Pikachu 上等兵 (475 威望)
0 投票
1 回复 48 阅读
0 投票
1 回复 56 阅读
0 投票
1 回复 46 阅读
用户头像 提问 2012年 12月1日 @ Nasus 上等兵 (329 威望)

欢迎来到随意问技术百科, 这是一个面向专业开发者的IT问答网站,提供途径助开发者查找IT技术方案,解决程序bug和网站运维难题等。
温馨提示:本网站禁止用户发布与IT技术无关的、粗浅的、毫无意义的或者违法国家法规的等不合理内容,谢谢支持。

欢迎访问随意问技术百科,为了给您提供更好的服务,请及时反馈您的意见。
...