php 带有 file_get_contents 的 HTTP 请求,获取响应代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15620124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:38:10  来源:igfitidea点击:

HTTP requests with file_get_contents, getting the response code

phpfilehttpstream

提问by georg

I'm trying to use file_get_contentstogether with stream_context_createto make POST requests. My code so far:

我正在尝试file_get_contents与 with 一起使用stream_context_create来发出 POST 请求。到目前为止我的代码:

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

It works fine, however, when an HTTP error occurs, it spits out a warning:

它工作正常,但是,当发生 HTTP 错误时,它会发出警告:

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

and returns false. Is there a way to:

并返回假。有没有办法:

  • 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
  • 抑制警告(我打算在失败的情况下抛出我自己的异常)
  • 从流中获取错误信息(至少是响应码)

回答by Alles

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

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

回答by mindplay.dk

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

没有一个答案(包括 OP 接受的答案)实际上满足两个要求:

  • 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-200response, but you can easily work from there, e.g. add a simple Responseclass and return new Response((int) $status, $response);if that fits your use-case better.

这将引发无200响应,但您可以轻松地从那里开始工作,例如添加一个简单的Response类,return new Response((int) $status, $response);如果它更适合您的用例。

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

例如,要POST对 API 端点执行 JSON :

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

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

请注意"ignore_errors" => truehttp上下文映射中的使用- 这将防止函数为非 2xx 状态代码抛出错误。

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.

对于大多数用例,这很可能是“正确”的错误抑制量 - 我不建议使用@错误抑制运算符,因为这也会抑制错误,例如简单地传递错误的参数,这可能会无意中隐藏错误调用代码。

回答by hamboy75

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

在接受的响应中添加更多行以获取 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);

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

隐藏错误输出两个注释都可以,ignore_errors = true 或@(我更喜欢@)

回答by Besen

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

@file_get_contents并且ignore_errors = true不一样:第一个不返回任何内容;第二个抑制错误消息,但返回服务器响应(例如 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).

它返回 200(好的)或 400(错误的请求)。

It works perfectly and it's easier than cURL.

它工作得很好,而且比 cURL 更容易。

回答by Kaarel

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