HTTP requests with file_get_contents, getting the response code

前端 未结 5 2128
眼角桃花
眼角桃花 2020-11-27 15:39

I\'m trying to use file_get_contents together with stream_context_create to make POST requests. My code so far:

    $options = arra         


        
相关标签:
5条回答
  • 2020-11-27 15:59

    @file_get_contents and ignore_errors = true are not the same: the first doesn't return anything; the second suppresses error messages, but returns server response (e.g. 400 Bad request).

    I use a function like this:

    $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;
    

    It returns 200 (Ok) or 400 (Bad request).

    It works perfectly and it's easier than cURL.

    0 讨论(0)
  • 2020-11-27 16:02

    None of the answers (including the one accepted by OP) actually satisfy the two requirements:

    • suppress a warning (I'm planning to throw my own exception in case of failure)
    • obtain the error information (at least, the response code) from the stream

    Here's my take:

    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;
    }
    

    This will throw for a non-200 response, but you can easily work from there, e.g. add a simple Response class and return new Response((int) $status, $response); if that fits your use-case better.

    For example, to do a JSON POST to an API endpoint:

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

    Note the use of "ignore_errors" => true in the http context map - this will prevent the function from throwing errors for non-2xx status codes.

    This is most likely the "right" amount of error-suppression for most use-cases - I do not recommend using the @ error-suppression operator, as this will also suppress errors like simply passing the wrong arguments, which could inadvertently hide a bug in calling code.

    0 讨论(0)
  • 2020-11-27 16:11

    Adding few more lines to the accepted response to get the http code

    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);
    

    to hide the error output both comments are ok, ignore_errors = true or @ (I prefer @)

    0 讨论(0)
  • 2020-11-27 16:15

    http://php.net/manual/en/reserved.variables.httpresponseheader.php

    file_get_contents("http://example.com", false, stream_context_create(['http' => ['ignore_errors' => true]]));
    var_dump($http_response_header);
    
    0 讨论(0)
  • 2020-11-27 16:16

    I go to this page with kind of a different issue, so posting my answer. My problem was that I was just trying to suppress the warning notification and display a customized warning message for the user, so this simple and obvious fix helped me:

    // Suppress the warning messages
    error_reporting(0);
    
    $contents = file_get_contents($url);
    if ($contents === false) {
      print 'My warning message';
    }
    

    And if needed, turn back error reporting after that:

    // Enable warning messages again
    error_reporting(-1);
    
    0 讨论(0)
提交回复
热议问题