file_get_contents로 HTTP 요청, 응답 코드 받기


87

POST 요청을 만들기 위해 file_get_contents함께 사용하려고 stream_context_create합니다. 지금까지 내 코드 :

    $options = array('http' => array(
        'method'  => 'POST',
        'content' => $data,
        'header'  => 
            "Content-Type: text/plain\r\n" .
            "Content-Length: " . strlen($data) . "\r\n"
    ));
    $context  = stream_context_create($options);
    $response = file_get_contents($url, false, $context);

잘 작동하지만 HTTP 오류가 발생하면 경고를 내 보냅니다.

file_get_contents(...): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request

거짓을 반환합니다. 방법이 있습니까?

  • 경고를 억제합니다 (실패한 경우 내 자신의 예외를 던질 계획입니다).
  • 스트림에서 오류 정보 (적어도 응답 코드)를 가져옵니다.

답변:



19

OP에서 수락 한 답변을 포함하여 어떤 답변도 실제로 두 가지 요구 사항을 충족하지 않습니다.

  • 경고를 억제합니다 (실패한 경우 내 자신의 예외를 던질 계획입니다).
  • 스트림에서 오류 정보 (적어도 응답 코드)를 가져옵니다.

내 의견은 다음과 같습니다.

function fetch(string $method, string $url, string $body, array $headers = []) {
    $context = stream_context_create([
        "http" => [
            // http://docs.php.net/manual/en/context.http.php
            "method"        => $method,
            "header"        => implode("\r\n", $headers),
            "content"       => $body,
            "ignore_errors" => true,
        ],
    ]);

    $response = file_get_contents($url, false, $context);

    /**
     * @var array $http_response_header materializes out of thin air
     */

    $status_line = $http_response_header[0];

    preg_match('{HTTP\/\S*\s(\d{3})}', $status_line, $match);

    $status = $match[1];

    if ($status !== "200") {
        throw new RuntimeException("unexpected response status: {$status_line}\n" . $response);
    }

    return $response;
}

이것은 200무응답 을 던질 것이지만, 예를 들어 간단한 Response클래스를 추가하고 return new Response((int) $status, $response);유스 케이스에 더 적합하다면 거기에서 쉽게 작업 할 수 있습니다 .

예를 들어 POSTAPI 엔드 포인트에 JSON을 수행하려면 다음을 수행하십시오 .

$response = fetch(
    "POST",
    "http://example.com/",
    json_encode([
        "foo" => "bar",
    ]),
    [
        "Content-Type: application/json",
        "X-API-Key: 123456789",
    ]
);

컨텍스트 맵 "ignore_errors" => true에서를 사용 http하면 함수가 비 -2xx 상태 코드에 대해 오류를 발생시키지 않도록 방지 할 수 있습니다.

이것은 대부분의 사용 사례에서 "적절한"오류 억제의 양일 가능성이 높습니다. @오류 억제 연산자를 사용하지 않는 것이 좋습니다. 이는 단순히 잘못된 인수를 전달하는 것과 같은 오류를 억제하므로 실수로 버그를 숨길 수 있습니다. 호출 코드.


5

http 코드를 얻기 위해 수락 된 응답에 몇 줄 더 추가

function getHttpCode($http_response_header)
{
    if(is_array($http_response_header))
    {
        $parts=explode(' ',$http_response_header[0]);
        if(count($parts)>1) //HTTP/1.0 <code> <text>
            return intval($parts[1]); //Get code
    }
    return 0;
}

@file_get_contents("http://example.com");
$code=getHttpCode($http_response_header);

오류 출력을 숨기려면 두 주석 모두 괜찮습니다. ignore_errors = true 또는 @ (@ 선호합니다)


-1

나는 다른 종류의 문제 로이 페이지로 이동하므로 내 답변을 게시합니다. 내 문제는 경고 알림을 억제하고 사용자에게 사용자 지정 경고 메시지를 표시하려고했기 때문에이 간단하고 분명한 수정이 도움이되었습니다.

// Suppress the warning messages
error_reporting(0);

$contents = file_get_contents($url);
if ($contents === false) {
  print 'My warning message';
}

그리고 필요한 경우 그 후에 오류보고를 되돌립니다.

// Enable warning messages again
error_reporting(-1);

-2

@file_get_contents그리고 ignore_errors = true동일하지 않습니다. 첫 번째는 아무것도 반환하지 않습니다. 두 번째는 오류 메시지를 억제하지만 서버 응답을 반환합니다 (예 : 400 잘못된 요청).

다음과 같은 기능을 사용합니다.

$result = file_get_contents(
  $url_of_API, 
  false, 
  stream_context_create([
    'http' => [
      'content' => json_encode(['value1' => $value1, 'value2' => $value2]), 
      'header' => 'Authorization: Basic XXXXXXXXXXXXXXX', 
      'ignore_errors' => 1, 
      'method' => 'POST', 
      'timeout' => 10
    ]
  ])
);

return json_decode($result)->status;

200 (Ok) 또는 400 (Bad request)을 반환합니다.

완벽하게 작동하며 cURL보다 쉽습니다.


그리고 이것이 질문을 어떻게 해결합니까? 응답 코드를받는 방법을 설명해 주시겠습니까?
Nico Haase

@Nico 내 솔루션에 대해 어떻게 생각하십니까?
Besen

당신은 JSON 결과를하지 구문 분석 및 명명 된 임의의 필드를 읽을 때 그것은 여전히 나쁜 하나 status는 API 호출에 대한 HTTP 상태 코드에 아무 관련이 없습니다 -
니코 하세

내가 연결하는 RESTful API가 JSON 응답을 반환하고 내 목적 (200 또는 400)을 위해 알아야하는 정보가 "status"필드에 포함되어 있음이 분명합니다. 그게 내가 필요한 전부이고 그게 내가 얻는 전부입니다. HTTP 상태 코드를 알아야하는 경우 다음과 같이하십시오. return $ http_response_header [0]; 그러나 @file_get_contents에서는 작동하지 않습니다.
Besen

그리고 이것은 원래의 질문에 어떻게 대답합니까? $http_response_header[0]높은 찬성 응답 인은 왜 작동하지 않는다고 생각 file_get_contents하십니까?
Nico Haase
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.