Saltar al contenido

PHP: ¿Cómo enviar un código de respuesta HTTP?

Solución:

Encontré esta pregunta y pensé que necesitaba una respuesta más completa:

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

Ensamblar el código de respuesta por su cuenta (PHP> = 4.0)

los 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 HTTP RFC, el frase de razón puede ser cualquier cadena personalizada (que cumpla con el estándar), pero en aras de la compatibilidad del 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, hay algunos problemas al usar esa primera variante. El mayor de los cuales creo 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 establecer el código de respuesta de manera algo cómoda, pero su uso requiere que el primer argumento sea una cadena no vacía. Aquí hay dos opciones:

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

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

Función http_response_code (PHP> = 5.4)

los 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 he preparado cuando necesitaba compatibilidad por debajo de 5.4 pero quería la funcionalidad del “nuevo” 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;
    }
}

Desafortunadamente, encontré que las soluciones presentadas por @dualed tienen varios defectos.

  1. Utilizando 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 – usando header('X-PHP-Response-Code: 404', true, 404); funciona correctamente en 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() resultar en un comportamiento inesperado:

    • Cuando PHP encuentra un código de respuesta HTTP que no comprende, PHP reemplazará el código por uno que conozca del mismo grupo. Por ejemplo, “521 Web server is down” se reemplaza por “500 Internal Server Error”. 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 resultar en un extraño encabezado “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í está la lista completa de códigos de estado de respuesta HTTP (esta lista incluye códigos de los estándares de Internet IETF, así como otros RFC IETF. Muchos de ellos NO son actualmente compatibles con la función http_response_code de PHP): http: //en.wikipedia .org / wiki / List_of_HTTP_status_codes

Puede probar fácilmente este error llamando a:

http_response_code(521);

El servidor enviará un código de respuesta HTTP “500 Internal Server Error” que dará como resultado 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. Debe detectarse el protocolo actual.

Se agradecen las pruebas y los comentarios.

desde PHP 5.4 puedes usar http_response_code() para obtener y establecer 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_response_code

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *