2011-12-23 10 views
0

저는 PHP 클라이언트에서 API를 사용하고 있으며 Curl을 사용하여 요청합니다. 모두 잘 진행되지만 응답 HTTP 코드가 400 이상이면 응답에서 헤더를 가져올 수 없습니다.오류 발생시 Curl 응답 헤더

내 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); 
+0

나 코드보기! – RageZ

+0

사용자 지정 헤더를 보내지 않아야 할 수도 있습니다. 응답 문자열로 오류 문자열을 보내는 것이 더 나을 것입니다. 그리고 어떻게 400보다 적은 응답으로 헤더를 얻고 있습니까? cURL php docs를 살펴보면 응답 헤더를 얻는 데 아무 것도 보이지 않습니다. 어쩌면 내가 뭔가를 놓친거야? – Corbin

+0

CURLOPT_HTTP200ALIASES 설정을 사용하여 오류 코드를 성공으로 추가 할 수 있습니다. – Sjoerd

답변

1

당신은 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);