[英]HTTP requests with file_get_contents, getting the response code
I'm trying to use file_get_contents
together with stream_context_create
to make POST requests.我正在尝试将
file_get_contents
与stream_context_create
一起使用来发出 POST 请求。 My code so far:到目前为止我的代码:
$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:
有没有办法:
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);
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- 200
response, but you can easily work from there, eg add a simple Response
class and return new Response((int) $status, $response);
这将引发非
200
响应,但您可以轻松地从那里开始工作,例如添加一个简单的Response
类并return new Response((int) $status, $response);
if that fits your use-case better.如果这更适合您的用例。
For example, to do a JSON POST
to an API endpoint:例如,要对 API 端点执行 JSON
POST
:
$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.请注意在
http
上下文映射中使用"ignore_errors" => true
- 这将防止函数抛出非 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.对于大多数用例,这很可能是“正确”的错误抑制量 - 我不建议使用
@
error-suppression 运算符,因为这也会抑制错误,例如简单地传递错误的参数,这可能会无意中隐藏错误在调用代码中。
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 或@(我更喜欢@)
To capture the error message when file_get_contents
returns FALSE, write a function which uses ob_start
and ob_get_contents
to capture the error message that file_get_contents
writes to stderr
.要在
file_get_contents
返回 FALSE 时捕获错误消息,请编写一个 function,它使用ob_start
和ob_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 ];
}
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);
@file_get_contents
and ignore_errors = true
are not the same: the first doesn't return anything; @file_get_contents
和@file_get_contents
ignore_errors = true
不一样:第一个不返回任何内容; the second suppresses error messages, but returns server response (eg 400 Bad request).第二个抑制错误消息,但返回服务器响应(例如 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 更容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.