如何在加载整个内容/页面/文件之前使用PHP获取标头?

时间:2013-02-13 21:57:41

标签: php get-headers

背景资料:

  • 我正在网上从各种来源动态收集一些网址。
  • 如果是HTML页面或图片,我想获取网址的内容。
  • 我不想加载大文件(如下载zip,pdf或 其他) - 只是意识到目标对我来说并不感兴趣。

有没有办法在实际获取内容之前用PHP检查响应类型/格式?(以避免浪费我自己和目标服务器的资源和带宽)

(我在PHP文档中找到get_headers(),但我不清楚,如果函数实际获取整个内容并返回标题,或者以某种方式仅从服务器获取标题,而不下载内容首先。我也找到了使用CURL和fsocketopen获取头文件的解决方案,但问题仍然存在,如果我可以在不加载实际内容的情况下完成它)

3 个答案:

答案 0 :(得分:3)

尝试使用HTTP HEAD 请求仅检索标头。类似的东西:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD');

或(手册推荐):

curl_setopt($ch, CURLOPT_NOBODY, true);

(我没有测试其中任何一个。)

答案 1 :(得分:1)

有一个PHP函数:

$headers=get_headers("http://www.amazingjokes.com/img/2014/530c9613d29bd_CountvonCount.jpg");
print_r($headers);

返回以下内容:

Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Date: Tue, 11 Mar 2014 22:44:38 GMT
    [2] => Server: Apache
    [3] => Last-Modified: Tue, 25 Feb 2014 14:08:40 GMT
    [4] => ETag: "54e35e8-8873-4f33ba00673f4"
    [5] => Accept-Ranges: bytes
    [6] => Content-Length: 34931
    [7] => Connection: close
    [8] => Content-Type: image/jpeg
)

此后应该很容易获得内容类型。

More reading here (PHP.NET)

答案 2 :(得分:0)

这是一个使用cURL和CURLOPT_WRITEFUNCTION回调函数的解决方案。在其中,我检查传入的标头以查找内容类型。如果它不是我们想要的,它会告诉cURL中止,所以你不要浪费时间来获取请求的主体。

$ch = curl_init('http://stackoverflow.com/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);

$data = '';
$haveHeader = false;

curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $chunk) use (&$haveHeader, &$data) {
    if (!$haveHeader && ($chunk == "\n" || $chunk == "\r\n")) {
        // detected end of header
        $haveHeader = true;
    } else if (!$haveHeader) {
        // detected content type
        if (preg_match('/content-type:\s*([^;]+)/i', $chunk, $matches)) {
            $contentType = strtolower($matches[1]);
            // check if content type is what we want
            if ($contentType != 'text/html' && strpos($contentType, 'image/') === false) {
                // tell curl to abort
                return false;
            }
        }
    } else {
        // append to data (body/content)
        $data .= $chunk;
    }

    return strlen($chunk);
});

if (curl_exec($ch)) {
    // use $data here
    echo strlen($data);
}