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



我试图使用file_get_contentsstream_context_create一起进行POST请求。我的代码到目前为止:

    $options = array('http' => array(
        'method'  => 'POST',
        'content' => $data,
        'header'  => 
            "Content-Type: text/plainrn" .
            "Content-Length: " . strlen($data) . "rn"
    ));
    $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。有没有办法:

  • 抑制警告(我计划在失败的情况下抛出我自己的异常)
  • 从流
  • 获取错误信息(至少是响应码)

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

没有一个答案(包括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("rn", $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);,如果这更适合你的用例。

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

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

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

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

在接受的响应中再添加几行以获得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);

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

为了捕获file_get_contents返回FALSE时的错误消息,编写一个函数,使用ob_startob_get_contents捕获file_get_contents写入stderr的错误消息。

function fileGetContents( $fileName )
{
  $errmsg = '' ;
  ob_start( ) ;
  $contents = file_get_contents( $fileName );
  if ( $contents === FALSE )
  {
    $errmsg = ob_get_contents( ) ;
    $errmsg .= "nfile name:$fileName";
    $contents = '' ;
  }
  ob_end_clean( ) ;
  return (object)[ 'errmsg' => $errmsg, 'contents' => $contents ];
}

我带着不同的问题来到这个页面,所以发表了我的答案。我的问题是,我只是试图抑制警告通知,并为用户显示一个自定义的警告消息,所以这个简单而明显的修复帮助了我:

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

@file_get_contentsignore_errors = true不一样:第一个不返回任何东西;第二个抑制错误消息,但返回服务器响应(例如400 Bad request)。

我使用这样一个函数:

$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(错误请求)。

它工作完美,比cURL更容易。

相关内容

  • 没有找到相关文章

最新更新