Żadna z odpowiedzi (w tym ta zaakceptowana przez OP) nie spełnia w rzeczywistości dwóch wymagań:
- pominąć ostrzeżenie (planuję zgłosić własny wyjątek w przypadku niepowodzenia)
- uzyskać informacje o błędzie (przynajmniej kod odpowiedzi) ze strumienia
Oto moja opinia:
function fetch(string $method, string $url, string $body, array $headers = []) {
$context = stream_context_create([
"http" => [
"method" => $method,
"header" => implode("\r\n", $headers),
"content" => $body,
"ignore_errors" => true,
],
]);
$response = file_get_contents($url, false, $context);
$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;
}
Spowoduje to brak 200
odpowiedzi, ale możesz łatwo z tego miejsca pracować, np. Dodać prostą Response
klasę i return new Response((int) $status, $response);
jeśli to lepiej pasuje do twojego przypadku użycia.
Na przykład, aby wykonać JSON POST
do punktu końcowego API:
$response = fetch(
"POST",
"http://example.com/",
json_encode([
"foo" => "bar",
]),
[
"Content-Type: application/json",
"X-API-Key: 123456789",
]
);
Zwróć uwagę na użycie "ignore_errors" => true
w http
mapie kontekstu - zapobiegnie to generowaniu przez funkcję błędów dla kodów stanu innych niż 2xx.
Jest to najprawdopodobniej „właściwa” wielkość pomijania błędów dla większości przypadków użycia - nie polecam używania @
operatora eliminacji błędów, ponieważ spowoduje to również wyeliminowanie błędów, takich jak zwykłe przekazanie niewłaściwych argumentów, które mogą przypadkowo ukryć błąd w kod wywołujący.
'ignore_errors' => TRUE
do$options
.