wake-up-neo.com

PHP: Wie versende ich einen HTTP-Antwortcode?

Ich habe ein PHP Skript, das Antworten mit HTTP-Antwortcodes (Statuscodes) wie HTTP 200 OK oder einem 4XX- oder 5XX-Code erstellen muss.

Wie kann ich das in PHP machen?

221
Paulo Coghi

Ich habe gerade diese Frage gefunden und dachte, dass es eine umfassendere Antwort braucht:

Ab PHP 5.4 gibt es drei Methoden, um dies zu erreichen:

Den Antwortcode selbst zusammenstellen (PHP> = 4.0)

Die Funktion header() hat einen speziellen Anwendungsfall, bei dem eine HTTP-Antwortzeile erkannt und durch eine benutzerdefinierte ersetzt wird

header("HTTP/1.1 200 OK");

Dies erfordert jedoch eine spezielle Behandlung für (schnelles) CGI-PHP:

$sapi_type = php_sapi_name();
if (substr($sapi_type, 0, 3) == 'cgi')
    header("Status: 404 Not Found");
else
    header("HTTP/1.1 404 Not Found");

Hinweis: Gemäß HTTP RFC kann der Ausdruck reason phrase eine beliebige benutzerdefinierte Zeichenfolge sein (das entspricht dem Standard), aber aus Gründen der Client-Kompatibilität empfehle ich nicht, eine zufällige Zeichenfolge dort abzulegen.

Hinweis: php_sapi_name() erfordert PHP 4.0.1

3. Argument zur Header-Funktion (PHP> = 4.3)

Es gibt offensichtlich ein paar Probleme bei der Verwendung dieser ersten Variante. Das größte, von dem ich denke, dass es teilweise von PHP oder dem Webserver analysiert und schlecht dokumentiert wird.

Seit 4.3 verfügt die Funktion header über ein drittes Argument, mit dem Sie den Antwortcode einigermaßen bequem festlegen können. Für dessen Verwendung muss das erste Argument jedoch eine nicht leere Zeichenfolge sein. Hier sind zwei Optionen:

header(':', true, 404);
header('X-PHP-Response-Code: 404', true, 404);

Ich empfehle die 2. . Das erste funktioniert funktioniert mit allen Browsern, die ich getestet habe, aber einige kleinere Browser oder Webcrawler haben möglicherweise ein Problem mit einer Kopfzeile, die nur einen Doppelpunkt enthält. Der Header-Feldname im 2.. Die Variante ist natürlich in keiner Weise standardisiert und könnte modifiziert werden. Ich habe nur einen hoffentlich beschreibenden Namen gewählt.

http_response_code Funktion (PHP> = 5.4)

Die http_response_code() -Funktion wurde in PHP 5.4 eingeführt und hat die Dinge stark gemacht einfacher.

http_response_code(404);

Das ist alles.

Kompatibilität

Hier ist eine Funktion, die ich mir ausgedacht habe, als ich Kompatibilität unter 5.4 brauchte, aber die Funktionalität der Funktion "new" http_response_code Wollte. Ich glaube PHP 4.3 ist mehr als genug Abwärtskompatibilität, aber man weiß nie ...

// For 4.3.0 <= PHP <= 5.4.0
if (!function_exists('http_response_code'))
{
    function http_response_code($newcode = NULL)
    {
        static $code = 200;
        if($newcode !== NULL)
        {
            header('X-PHP-Response-Code: '.$newcode, true, $newcode);
            if(!headers_sent())
                $code = $newcode;
        }       
        return $code;
    }
}
418
dualed

Leider habe ich festgestellt, dass die von @dualed vorgestellten Lösungen verschiedene Mängel aufweisen.

  1. Die Verwendung von substr($sapi_type, 0, 3) == 'cgi' ist nicht ausreichend, um schnelle CGI zu erkennen. Bei Verwendung von PHP-FPM FastCGI Process Manager gibt php_sapi_name() fpm nicht cgi zurück

  2. Fasctcgi und php-fpm decken einen weiteren von @Josh erwähnten Fehler auf - die Verwendung von header('X-PHP-Response-Code: 404', true, 404); funktioniert ordnungsgemäß unter PHP-FPM (FastCGI)

  3. header("HTTP/1.1 404 Not Found"); kann fehlschlagen, wenn das Protokoll nicht HTTP/1.1 ist (d. h. 'HTTP/1.0'). Das aktuelle Protokoll muss mit $_SERVER['SERVER_PROTOCOL'] (Verfügbar seit PHP 4.1.0

  4. Es gibt mindestens 2 Fälle, in denen der Aufruf von http_response_code() zu unerwartetem Verhalten führt:

    • Wenn PHP auf einen HTTP-Antwortcode stößt, den es nicht versteht, ersetzt PHP den Code durch einen Code, den es aus derselben Gruppe kennt. Beispiel: "521 Webserver ist ausgefallen "wird durch" 500 Internal Server Error "ersetzt. Viele andere ungewöhnliche Antwortcodes aus anderen Gruppen 2xx, 3xx, 4xx werden auf diese Weise behandelt.
    • Auf einem Server mit php-fpm und nginx kann die Funktion http_response_code () den Code wie erwartet ändern, die Nachricht jedoch nicht. Dies kann beispielsweise zu einem seltsamen "404 OK" -Header führen. Dieses Problem wird auch auf der PHP Website durch einen Benutzerkommentar erwähnt http://www.php.net/manual/en/function.http-response-code.php#11242

Als Referenz finden Sie hier die vollständige Liste der HTTP-Antwortstatuscodes (diese Liste enthält Codes aus IETF-Internetstandards sowie andere IETF-RFCs. Viele von ihnen werden derzeit NICHT von der Funktion PHP http_response_code) unterstützt ): http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Sie können diesen Fehler einfach testen, indem Sie Folgendes aufrufen:

http_response_code(521);

Der Server sendet den HTTP-Antwortcode "500 Internal Server Error", was zu unerwarteten Fehlern führt, wenn Sie beispielsweise eine benutzerdefinierte Clientanwendung haben, die Ihren Server aufruft und einige zusätzliche HTTP-Codes erwartet.


Meine Lösung (für alle PHP Versionen seit 4.1.0):

$httpStatusCode = 521;
$httpStatusMsg  = 'Web server is down';
$phpSapiName    = substr(php_sapi_name(), 0, 3);
if ($phpSapiName == 'cgi' || $phpSapiName == 'fpm') {
    header('Status: '.$httpStatusCode.' '.$httpStatusMsg);
} else {
    $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
    header($protocol.' '.$httpStatusCode.' '.$httpStatusMsg);
}

Fazit

die Implementierung von http_response_code () unterstützt nicht alle HTTP-Antwortcodes und überschreibt möglicherweise den angegebenen HTTP-Antwortcode mit einem anderen aus derselben Gruppe.

Die neue Funktion http_response_code () behebt nicht alle Probleme, führt jedoch zu neuen Fehlern.

Die von @dualed angebotene "Kompatibilitäts" -Lösung funktioniert zumindest unter PHP-FPM nicht wie erwartet.

Die anderen von @dualed angebotenen Lösungen weisen ebenfalls verschiedene Fehler auf. Die schnelle CGI-Erkennung unterstützt kein PHP-FPM. Aktuelles Protokoll muss erkannt werden.

Alle Tests und Kommentare sind willkommen.

37
Grigore Madalin

seit PHP 5.4 können Sie http_response_code() verwenden, um den Header-Statuscode abzurufen und festzulegen.

hier ein beispiel:

<?php

// Get the current response code and set a new one
var_dump(http_response_code(404));

// Get the new response code
var_dump(http_response_code());
?>

hier ist das Dokument dieser Funktion in php.net:

http_response_code

16

Fügen Sie diese Zeile vor jeder Ausgabe des Körpers hinzu, falls Sie keine Ausgabepufferung verwenden.

header("HTTP/1.1 200 OK");

Ersetzen Sie den Nachrichtenteil ('OK') durch die entsprechende Nachricht und den Statuscode durch Ihren Code (404, 501 usw.).

8
sparkey0

Wenn Sie hier sind, weil Wordpress beim Laden der Umgebung 404-Werte angegeben haben, sollte dies das Problem beheben:

define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
status_header( 200 );
//$wp_query->is_404=false; // if necessary

Das Problem ist darauf zurückzuführen, dass der Header "Status: 404 Not Found" gesendet wurde. Sie müssen das überschreiben. Dies wird auch funktionieren:

define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
header("HTTP/1.1 200 OK");
header("Status: 200 All rosy");
7
jaggedsoft

Mit der Header Funktion. Im Abschnitt zum ersten Parameter finden Sie ein Beispiel.

6
Quentin
header("HTTP/1.1 200 OK");
http_response_code(201);
header("Status: 200 All rosy");

http_response_code (200); funktioniert nicht, da die Testbenachrichtigung 404 https://developers.google.com/speed/pagespeed/insights/

2
alpc

Wir können unterschiedliche Rückgabewerte von http_response_code über die zwei verschiedenen Umgebungen erhalten:

  1. Webserver-Umgebung
  2. CLI-Umgebung

Geben Sie in der Webserverumgebung den vorherigen Antwortcode zurück, wenn Sie einen Antwortcode angegeben haben oder wenn Sie keinen Antwortcode angeben, wird der aktuelle Wert gedruckt. Der Standardwert ist 200 (OK).

In der CLI-Umgebung wird true zurückgegeben, wenn Sie einen Antwortcode angegeben haben, und false, wenn Sie keinen response_code angegeben haben.

Beispiel einer Webserver-Umgebung für den Rückgabewert von Response_code:

var_dump(http_respone_code(500)); // int(200)
var_dump(http_response_code()); // int(500)

Beispiel für die CLI-Umgebung des Rückgabewerts von Response_code:

var_dump(http_response_code()); // bool(false)
var_dump(http_response_code(501)); // bool(true)
var_dump(http_response_code()); // int(501)
1
GaziAnis