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?
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:
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
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.
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.
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;
}
}
Leider habe ich festgestellt, dass die von @dualed vorgestellten Lösungen verschiedene Mängel aufweisen.
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
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)
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
Es gibt mindestens 2 Fälle, in denen der Aufruf von http_response_code()
zu unerwartetem Verhalten führt:
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.
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:
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.).
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");
Mit der Header Funktion. Im Abschnitt zum ersten Parameter finden Sie ein Beispiel.
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/
Wir können unterschiedliche Rückgabewerte von http_response_code über die zwei verschiedenen Umgebungen erhalten:
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)