Pregunta

Tengo un script PHP que necesita generar respuestas con códigos de respuesta HTTP (códigos de estado), como HTTP 200 OK, o algún código 4XX o 5XX.

¿Cómo puedo hacer esto en PHP?

¿Fue útil?

Solución

Acabo de encontrar esta pregunta y pensé que necesitaba una respuesta más completa:

A partir de PHP 5.4 Hay tres métodos para lograr esto:

Armando el código de respuesta por tu cuenta (PHP >= 4.0)

El header() La función tiene un caso de uso especial que detecta una línea de respuesta HTTP y le permite reemplazarla por una personalizada.

header("HTTP/1.1 200 OK");

Sin embargo, esto requiere un tratamiento especial para PHP CGI (rápido):

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

Nota: De acuerdo con la RFC HTTP, el frase de razon puede ser cualquier cadena personalizada (que cumpla con el estándar), pero por razones de compatibilidad con el cliente, no Recomiendo poner una cadena aleatoria allí.

Nota: php_sapi_name() requiere PHP 4.0.1

3er argumento para la función de encabezado (PHP >= 4.3)

Obviamente existen algunos problemas al utilizar esa primera variante.Creo que el mayor de ellos es que está parcialmente analizado por PHP o el servidor web y está mal documentado.

Desde 4.3, el header La función tiene un tercer argumento que le permite configurar el código de respuesta con cierta comodidad, pero su uso requiere que el primer argumento sea una cadena que no esté vacía.Aquí hay dos opciones:

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

te recomiendo el 2do.La primera hace funciona en todos los navegadores que he probado, pero algunos navegadores menores o rastreadores web pueden tener problemas con una línea de encabezado que solo contiene dos puntos.El nombre del campo del encabezado en el 2do.Por supuesto, la variante no está estandarizada de ninguna manera y podría modificarse, solo elegí un nombre con suerte descriptivo.

Función http_response_code (PHP >= 5.4)

El http_response_code() La función se introdujo en PHP 5.4 e hizo que las cosas mucho más fácil.

http_response_code(404);

Eso es todo.

Compatibilidad

Aquí hay una función que preparé cuando necesitaba compatibilidad por debajo de 5.4 pero quería la funcionalidad de la "nueva" http_response_code función.Creo que PHP 4.3 es más que suficiente compatibilidad con versiones anteriores, pero nunca se sabe...

// 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;
    }
}

Otros consejos

Lamentablemente descubrí que las soluciones presentadas por @dualed tienen varios defectos.

  1. Usando substr($sapi_type, 0, 3) == 'cgi' no es suficiente para detectar CGI rápido.Al utilizar PHP-FPM FastCGI Process Manager, php_sapi_name() devuelve fpm no cgi

  2. Fasctcgi y php-fpm exponen otro error mencionado por @Josh: usar header('X-PHP-Response-Code: 404', true, 404); funciona correctamente bajo PHP-FPM (FastCGI)

  3. header("HTTP/1.1 404 Not Found"); puede fallar cuando el protocolo no es HTTP/1.1 (es decir,'HTTP/1.0').El protocolo actual debe detectarse utilizando $_SERVER['SERVER_PROTOCOL'] (disponible desde PHP 4.1.0

  4. Hay al menos 2 casos al llamar. http_response_code() resulta en un comportamiento inesperado:

    • Cuando PHP encuentra un código de respuesta HTTP que no comprende, PHP reemplazará el código con uno que conozca del mismo grupo.Por ejemplo, "el servidor web 521 no funciona" se reemplaza por "Error interno del servidor 500".Muchos otros códigos de respuesta poco comunes de otros grupos 2xx, 3xx, 4xx se manejan de esta manera.
    • En un servidor con php-fpm y nginx, la función http_response_code() PUEDE cambiar el código como se esperaba, pero no el mensaje.Esto puede dar como resultado un encabezado extraño "404 OK", por ejemplo.Este problema también se menciona en el sitio web de PHP mediante un comentario de usuario. http://www.php.net/manual/en/function.http-response-code.php#112423

Para su referencia, aquí encontrará la lista completa de códigos de estado de respuesta HTTP (esta lista incluye códigos de los estándares de Internet del IETF, así como otros RFC del IETF.Muchos de ellos NO son actualmente compatibles con la función PHP http_response_code): http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Puedes probar fácilmente este error llamando a:

http_response_code(521);

El servidor enviará el código de respuesta HTTP "500 Error interno del servidor", lo que provocará errores inesperados si, por ejemplo, tiene una aplicación cliente personalizada que llama a su servidor y espera algunos códigos HTTP adicionales.


Mi solución (para todas las versiones de PHP desde 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);
}

Conclusión

La implementación http_response_code() no admite todos los códigos de respuesta HTTP y puede sobrescribir el código de respuesta HTTP especificado con otro del mismo grupo.

La nueva función http_response_code() no resuelve todos los problemas involucrados, pero empeora las cosas al introducir nuevos errores.

La solución de "compatibilidad" ofrecida por @dualed no funciona como se esperaba, al menos bajo PHP-FPM.

Las otras soluciones ofrecidas por @dualed también tienen varios errores.La detección rápida de CGI no maneja PHP-FPM.Se debe detectar el protocolo actual.

Se agradecen todas las pruebas y comentarios.

desde PHP 5.4 puedes usar http_response_code() para obtener y configurar el código de estado del encabezado.

aquí un ejemplo:

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

aquí está el documento de esta función en php.net:

http_código_respuesta

Agregue esta línea antes de cualquier salida del cuerpo, en el caso de que no esté utilizando el búfer de salida.

header("HTTP/1.1 200 OK");

Reemplace la parte del mensaje ('OK') con el mensaje apropiado, y el código de estado con su código según corresponda (404, 501, etc.)

Si está aquí debido a que WordPress le da 404 al cargar el entorno, esto debería solucionar el problema:

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

El problema se debe a enviar un estado: 404 no encontrado encabezado.Tienes que anular eso. Esto también funcionará:

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

con el encabezado Función.Hay un ejemplo en la sección en el primer parámetro que toma.

Si su versión de PHP no incluye esta función:

<?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;
    }

We can get different return value from http_response_code via the two different environment:

  1. Web Server Environment
  2. CLI environment

At the web server environment, return previous response code if you provided a response code or when you do not provide any response code then it will be print the current value. Default value is 200 (OK).

At CLI Environment, true will be return if you provided a response code and false if you do not provide any response_code.

Example of Web Server Environment of Response_code's return value:

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

Example of CLI Environment of Response_code's return value:

var_dump(http_response_code()); // bool(false)
var_dump(http_response_code(501)); // bool(true)
var_dump(http_response_code()); // int(501)
header("HTTP/1.1 200 OK");
http_response_code(201);
header("Status: 200 All rosy");

http_response_code(200); not work because test alert 404 https://developers.google.com/speed/pagespeed/insights/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top