Nessuna delle risposte (compresa quella accettata da OP) soddisfa effettivamente i due requisiti:
- sopprimere un avviso (ho intenzione di lanciare la mia eccezione in caso di errore)
- ottenere le informazioni sull'errore (almeno il codice di risposta) dal flusso
Ecco la mia opinione:
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;
}
Questo genererà una mancata 200risposta, ma puoi facilmente lavorare da lì, ad esempio aggiungi una Responseclasse semplice e return new Response((int) $status, $response);se questo si adatta meglio al tuo caso d'uso.
Ad esempio, per eseguire un JSON POSTsu un endpoint API:
$response = fetch(
"POST",
"http://example.com/",
json_encode([
"foo" => "bar",
]),
[
"Content-Type: application/json",
"X-API-Key: 123456789",
]
);
Nota l'uso di "ignore_errors" => truenella httpmappa di contesto: ciò impedirà alla funzione di generare errori per codici di stato non 2xx.
Questa è molto probabilmente la quantità "giusta" di soppressione degli errori per la maggior parte dei casi d'uso - Non consiglio di usare l' @operatore di soppressione degli errori, poiché questo sopprimerà anche errori come il semplice passaggio di argomenti sbagliati, che potrebbero inavvertitamente nascondere un bug in codice chiamante.
'ignore_errors' => TRUEa$options.