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 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?
Antworten:
Ich habe gerade diese Frage gefunden und dachte, sie braucht eine umfassendere Antwort:
Ab PHP 5.4 gibt es drei Methoden, um dies zu erreichen:
Die header()
Funktion hat einen speziellen Anwendungsfall, der eine HTTP-Antwortzeile erkennt und Sie durch eine benutzerdefinierte ersetzen kann
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: Laut HTTP-RFC kann die Grundphrase eine beliebige benutzerdefinierte Zeichenfolge sein (die dem Standard entspricht). Aus Gründen der Clientkompatibilität empfehle ich jedoch nicht , dort eine zufällige Zeichenfolge einzufügen.
Hinweis: php_sapi_name()
erfordert PHP 4.0.1
Es gibt offensichtlich einige Probleme bei der Verwendung dieser ersten Variante. Das größte davon ist meiner Meinung nach, dass es teilweise von PHP oder dem Webserver analysiert und schlecht dokumentiert wird.
Seit 4.3 verfügt die header
Funktion über ein drittes Argument, mit dem Sie den Antwortcode etwas bequemer festlegen können. Für die Verwendung dieses Codes muss das erste Argument jedoch eine nicht leere Zeichenfolge sein. Hier sind zwei Möglichkeiten:
header(':', true, 404);
header('X-PHP-Response-Code: 404', true, 404);
Ich empfehle die zweite ein . Der erste funktioniert in allen von mir getesteten Browsern, aber einige kleinere Browser oder Webcrawler haben möglicherweise ein Problem mit einer Kopfzeile, die nur einen Doppelpunkt enthält. Der Name des Headerfeldes im 2 .. 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 Sache viel einfacher gemacht.
http_response_code(404);
Das ist alles.
Hier ist eine Funktion, die ich mir ausgedacht habe, als ich Kompatibilität unter 5.4 benötigte, aber die Funktionalität der "neuen" http_response_code
Funktion 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;
}
}
headers_sent()
immer gleich nach dem Anruf wahr sein header()
? (2) jemals etwas wie http_response_text () in der 5.4-Welt gefunden? Zumindest der alte Header () kann den Text nach dem Statuscode beeinflussen.
headers_sent()
ist wahr, wenn Sie keine weiteren Header hinzufügen können, weil der Inhalt bereits gesendet wurde, und nicht, wenn Sie einen Header hinzugefügt haben. (2) Entschuldigung, nein. Andere Sprachen haben jedoch eine bessere Unterstützung
http_response_code
(und vielleicht allgemeiner das Ändern des Headers) nach Ihnen echo
etwas nicht mehr funktioniert . Ich hoffe es hilft.
Leider habe ich festgestellt, dass die von @dualed vorgestellten Lösungen verschiedene Mängel aufweisen.
Die Verwendung substr($sapi_type, 0, 3) == 'cgi'
ist nicht ausreichend, um schnelles CGI zu erkennen. Bei Verwendung von PHP-FPM FastCGI Process Manager wird php_sapi_name()
fpm nicht cgi zurückgegeben
Fasctcgi und php-fpm decken einen weiteren von @Josh erwähnten Fehler auf - die Verwendung header('X-PHP-Response-Code: 404', true, 404);
funktioniert unter PHP-FPM (FastCGI) ordnungsgemäß.
header("HTTP/1.1 404 Not Found");
kann fehlschlagen, wenn das Protokoll nicht HTTP / 1.1 ist (dh 'HTTP / 1.0'). Das aktuelle Protokoll muss mit $_SERVER['SERVER_PROTOCOL']
(verfügbar seit PHP 4.1.0) erkannt werden
Es gibt mindestens zwei Fälle, in denen ein Anruf 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 PHP-Funktion 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", der zu unerwarteten Fehlern führt, wenn beispielsweise eine benutzerdefinierte Clientanwendung 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 () löst nicht alle damit verbundenen Probleme, verschlimmert jedoch die Einführung neuer Fehler.
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. Das aktuelle Protokoll muss erkannt werden.
Alle Tests und Kommentare sind willkommen.
Seit PHP 5.4 können Sie http_response_code()
den Header-Statuscode abrufen und festlegen.
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 entsprechenden Code (404, 501 usw.).
Wenn Sie hier sind, weil Wordpress beim Laden der Umgebung 404 gibt, 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 ein Status: 404 Not Found-Header gesendet wird. Das muss man außer Kraft setzen. 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");
header("HTTP/1.1 200 OK");
http_response_code(201);
header("Status: 200 All rosy");
http_response_code (200); funktioniert nicht, weil Testalarm 404 https://developers.google.com/speed/pagespeed/insights/
Wenn Ihre PHP-Version diese Funktion nicht enthält:
<?php
function http_response_code($code = NULL) {
if ($code !== NULL) {
switch ($code) {
case 100: $text = 'Continue';
break;
case 101: $text = 'Switching Protocols';
break;
case 200: $text = 'OK';
break;
case 201: $text = 'Created';
break;
case 202: $text = 'Accepted';
break;
case 203: $text = 'Non-Authoritative Information';
break;
case 204: $text = 'No Content';
break;
case 205: $text = 'Reset Content';
break;
case 206: $text = 'Partial Content';
break;
case 300: $text = 'Multiple Choices';
break;
case 301: $text = 'Moved Permanently';
break;
case 302: $text = 'Moved Temporarily';
break;
case 303: $text = 'See Other';
break;
case 304: $text = 'Not Modified';
break;
case 305: $text = 'Use Proxy';
break;
case 400: $text = 'Bad Request';
break;
case 401: $text = 'Unauthorized';
break;
case 402: $text = 'Payment Required';
break;
case 403: $text = 'Forbidden';
break;
case 404: $text = 'Not Found';
break;
case 405: $text = 'Method Not Allowed';
break;
case 406: $text = 'Not Acceptable';
break;
case 407: $text = 'Proxy Authentication Required';
break;
case 408: $text = 'Request Time-out';
break;
case 409: $text = 'Conflict';
break;
case 410: $text = 'Gone';
break;
case 411: $text = 'Length Required';
break;
case 412: $text = 'Precondition Failed';
break;
case 413: $text = 'Request Entity Too Large';
break;
case 414: $text = 'Request-URI Too Large';
break;
case 415: $text = 'Unsupported Media Type';
break;
case 500: $text = 'Internal Server Error';
break;
case 501: $text = 'Not Implemented';
break;
case 502: $text = 'Bad Gateway';
break;
case 503: $text = 'Service Unavailable';
break;
case 504: $text = 'Gateway Time-out';
break;
case 505: $text = 'HTTP Version not supported';
break;
default:
exit('Unknown http status code "' . htmlentities($code) . '"');
break;
}
$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
header($protocol . ' ' . $code . ' ' . $text);
$GLOBALS['http_response_code'] = $code;
} else {
$code = (isset($GLOBALS['http_response_code']) ? $GLOBALS['http_response_code'] : 200);
}
return $code;
}
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 Antwortcode angegeben haben.
Beispiel für eine Webserverumgebung mit dem 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)
header('X-PHP-Response-Code: 404', true, 404);
dies unter PHP-FPM (FastCGI) ordnungsgemäß funktioniert