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

2022-08-30 07:43:17

我正在尝试与一起使用以发出POST请求。到目前为止,我的代码:file_get_contentsstream_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

并返回 false。有没有办法:

  • 禁止显示警告(我计划在失败时抛出自己的异常)
  • 从流中获取错误信息(至少是响应代码)

答案 1

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

$context = stream_context_create(['http' => ['ignore_errors' => true]]);
$result = file_get_contents("http://example.com", false, $context);
var_dump($http_response_header);

答案 2

没有一个答案(包括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;
}

这将抛出一个非响应,但你可以很容易地从那里工作,例如,添加一个简单的类,如果它更适合你的用例。200Responsereturn new Response((int) $status, $response);

例如,要对 API 端点执行 JSON 操作,请执行以下操作:POST

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

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

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


推荐