在使用CURL检索标题字符串后,如何在PHP中检索单个标题字段值?

时间:2011-04-07 18:54:02

标签: php regex curl http-headers preg-match

我正在使用CURL来执行HTTP请求。我得到这样的东西:

HTTP/1.1 200 OK
Date: Thu, 07 Apr 2011 15:52:33 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1

我的问题是,如何可靠地检索四个命名字段中的任何一个值?

现在我正在这样做:

$name = 'Expires';
preg_match('/^'.$name.': ([^\r\n]*)[\r\n]*$/m', $headers, $matches);

似乎工作正常。我只是好奇我的正则表达式将适用于我从服务器收到的每个格式良好的标题,或者如果存在差异,它会破坏。我似乎无法找到有效字符,换行符或回车的具体限制,因此我不知道所有值是否都遵循以下格式:

字段名后跟冒号,后跟空格,后跟非换行符,后跟换行符。

3 个答案:

答案 0 :(得分:2)

我认为没有办法可以打破。虽然,如果你知道顺序总是相同的,那么就不需要在regexp中包含变量名,只需要以分号开头即可。然后,您可以将其简化为

/:(.*)$/m

$应该在该行的末尾停止,而(.*)将导致您将在指定的组中包含变量值。如你所知,在上面的例子中应该有4组。

答案 1 :(得分:1)

PHP有一种内置的方法,可以使用http_parse_headers()来实现这一点,这必须是一种比滚动自己更好的方法。

http://php.net/manual/en/function.http-parse-headers.php

答案 2 :(得分:1)

我使用此代码并且到目前为止没有问题(当然远非理想的):

// $this->headers contains string with all headers
private function parseHeaders()
{
    $headers = array();
    foreach (explode("\n", $this->headers) as $line) {
        $line = trim($line);
        if (strpos($line, ':') !== false) {
            list($headerName, $headerValue) = explode(':', $line, 2);
            $headerValue = ltrim($headerValue);
            $headerName = strtolower(rtrim($headerName));
            if (isset($headers[$headerName])) {
                if (is_array($headers[$headerName])) {
                    $headers[$headerName][] = $headerValue;
                } else {
                    $headers[$headerName] = array(
                        $headers[$headerName],
                        $headerValue
                    );
                }
            } else {
                $headers[$headerName] = $headerValue;
            }
        }
    }
    return $headers;
}

但是,如果你想以最正确的方式做到这一点,我认为你应该阅读RFC 2616