it-swarm.com.de

HTTP-Anforderungen mit file_get_contents erhalten den Antwortcode

Ich versuche, file_get_contents zusammen mit stream_context_create für POST -Anfragen zu verwenden. Mein Code bisher:

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

Es funktioniert gut, wenn jedoch ein HTTP-Fehler auftritt, wird eine Warnung ausgegeben:

file_get_contents(...): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request

und gibt falsch zurück. Gibt es einen Weg zu:

  • eine Warnung unterdrücken (ich plane, im Fehlerfall meine eigene Ausnahme auszulösen)
  • die Fehlerinformationen (zumindest den Antwortcode) vom Stream erhalten
66
georg

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

file_get_contents("http://example.com");
var_dump($http_response_header);
122
Alles

Fügen Sie der akzeptierten Antwort einige weitere Zeilen hinzu, um den http-Code zu erhalten

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

um die Fehlerausgabe auszublenden, sind beide Kommentare in Ordnung, ignore_errors = true oder @ (ich bevorzuge @)

3
hamboy75

Keine der Antworten (einschließlich der vom OP akzeptierten) erfüllt tatsächlich die beiden Anforderungen:

  • eine Warnung unterdrücken (ich plane, im Fehlerfall meine eigene Ausnahme auszulösen)
  • die Fehlerinformationen (zumindest den Antwortcode) vom Stream erhalten

Hier ist mein 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;
}

Dadurch wird eine Antwort ausgegeben, die nicht -200 ist. Sie können jedoch problemlos von dort aus arbeiten, z. Fügen Sie eine einfache Response-Klasse und return new Response((int) $status, $response); hinzu, wenn dies besser zu Ihrem Anwendungsfall passt.

So führen Sie beispielsweise einen JSON POST für einen API-Endpunkt aus:

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

Beachten Sie die Verwendung von "ignore_errors" => true in der http-Kontextzuordnung. Dadurch wird verhindert, dass die Funktion Fehler für Nicht-2xx-Statuscodes auslöst.

Dies ist höchstwahrscheinlich die "richtige" Menge an Fehlerunterdrückung für die meisten Anwendungsfälle. Ich empfehle die Verwendung des @-Fehlerunterdrückungsoperators nicht, da dies auch Fehler unterdrückt, beispielsweise das Übergeben falscher Argumente, wodurch ein Fehler versehentlich ausgeblendet wird in aufrufendem Code.

2
mindplay.dk

Ich gehe auf diese Seite mit einer anderen Ausgabe und poste meine Antwort. Mein Problem war, dass ich nur versucht habe, die Warnmeldung zu unterdrücken und eine benutzerdefinierte Warnmeldung für den Benutzer anzuzeigen. Diese einfache und offensichtliche Lösung hat mir dabei geholfen:

// Suppress the warning messages
error_reporting(0);

$contents = file_get_contents($url);
if ($contents === false) {
  print 'My warning message';
}

Und falls nötig, schalten Sie die Fehlermeldung zurück:

// Enable warning messages again
error_reporting(-1);
0
Kaarel