错误时卷曲响应标头

时间:2011-12-23 10:12:44

标签: php http rest curl header

我正在使用我的API的PHP客户端,我正在使用Curl来执行请求。一切顺利,但当有一个400或更高的响应http代码时,我似乎无法从响应中获取标题。

要从所有响应中获取标头,因为我的API会在响应中添加额外的标头,并提供有关错误的更多信息。

如果有办法总是从Curl中的响应中获取标题?

    $ch = curl_init();

    // Convert headers to curlopts
    $headers_new = array();
    foreach($headers as $key => $value){
        if(isset($this->_header_to_curlopt[$key])){
            switch($key) {
                case self::HEADER_AUTHORIZATION:
                    if(strstr($value, 'Basic')) {
                        $value = base64_decode(trim(str_replace('Basic ', '', $value)));
                    }
                    break;
                case self::HEADER_COOKIE:
                    if(is_array($value)) {
                        $value = $this->cookieStringToArray($value);
                    }
                    break;
            }
            curl_setopt($ch, $this->_header_to_curlopt[$key], $value);
            unset($this->_requestHeaders[$key]);
        }else{
            $headers_new[] = $key . ': ' . $value;
        }
    }
    $headers = $headers_new;

    // Add length header if it is not set
    if(!isset($headers[self::HEADER_CONTENT_LENGTH])){
        if(is_array($data)) {
            $headers[self::HEADER_CONTENT_LENGTH] = strlen(http_build_query($data, '', '&'));
        } else {
            $headers[self::HEADER_CONTENT_LENGTH] = strlen($data);
        }
    }

    // Set headers
    if(count($headers)){
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        // Don't output content
    curl_setopt($ch ,CURLOPT_TIMEOUT, $timeout);        // Timeout

    switch($method){
        case self::METHOD_POST:
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            break;
        case self::METHOD_GET:
            if(count($this->_data)) {
                $separator = strstr($url, '?') ? '&' : '?';
                $url .= $separator . http_build_query($this->_data, '', '&');
            }
            break;
        default:
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); 
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
            break;
    }

    curl_setopt($ch, CURLOPT_FAILONERROR, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);

    // Use SSL
    if(strtolower(substr($url, 0, 5)) == 'https') {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    }
    $result = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    // Separate content and headers
    $result = str_replace("\r\n\r\nHTTP/", "\r\nHTTP/", $result);
    $parts = explode("\r\n\r\n",$result);
    $headers = array_shift($parts);
    $result = implode("\r\n\r\n", $parts);

1 个答案:

答案 0 :(得分:2)

您应该设置CURLOPT_HEADER标记,您可以使用curl_getinfo获取HTTP状态代码。

<?php 
$ch = curl_init('http://yoururl/'); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
$c = curl_exec($ch); 
echo curl_getinfo($ch, CURLINFO_HTTP_CODE);

来自您的代码

$ch = curl_init();

// Convert headers to curlopts
$headers_new = array();
foreach($headers as $key => $value){
    if(isset($this->_header_to_curlopt[$key])){
        switch($key) {
            case self::HEADER_AUTHORIZATION:
                if(strstr($value, 'Basic')) {
                    $value = base64_decode(trim(str_replace('Basic ', '', $value)));
                }
                break;
            case self::HEADER_COOKIE:
                if(is_array($value)) {
                    $value = $this->cookieStringToArray($value);
                }
                break;
        }
        curl_setopt($ch, $this->_header_to_curlopt[$key], $value);
        unset($this->_requestHeaders[$key]);
    }else{
        $headers_new[] = $key . ': ' . $value;
    }
}
$headers = $headers_new;
curl_setopt($ch, CURLOPT_HEADER, 1); 
// Add length header if it is not set
if(!isset($headers[self::HEADER_CONTENT_LENGTH])){
    if(is_array($data)) {
        $headers[self::HEADER_CONTENT_LENGTH] = strlen(http_build_query($data, '', '&'));
    } else {
        $headers[self::HEADER_CONTENT_LENGTH] = strlen($data);
    }
}

// Set headers
if(count($headers)){
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        // Don't output content
curl_setopt($ch ,CURLOPT_TIMEOUT, $timeout);        // Timeout

switch($method){
    case self::METHOD_POST:
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        break;
    case self::METHOD_GET:
        if(count($this->_data)) {
            $separator = strstr($url, '?') ? '&' : '?';
            $url .= $separator . http_build_query($this->_data, '', '&');
        }
        break;
    default:
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
        break;
}

curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);

// Use SSL
if(strtolower(substr($url, 0, 5)) == 'https') {
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
$result = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// Separate content and headers
$result = str_replace("\r\n\r\nHTTP/", "\r\nHTTP/", $result);
$parts = explode("\r\n\r\n",$result);
$headers = array_shift($parts);
$result = implode("\r\n\r\n", $parts);