Pergunta

Eu tenho um script PHP que precisa fazer respostas com códigos de resposta HTTP (códigos de status), como HTTP 200 OK, ou algum código 4XX ou 5XX.

Como posso fazer isso em PHP?

Foi útil?

Solução

Acabei de encontrar esta pergunta e pensei que precisa de uma resposta mais abrangente:

A partir de PHP 5.4 existem três métodos para fazer isso:

Montando você mesmo o código de resposta (PHP >= 4.0)

O header() função tem um caso de uso especial que detecta uma linha de resposta HTTP e permite substituí-la por uma personalizada

header("HTTP/1.1 200 OK");

No entanto, isso requer tratamento 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");

Observação: De acordo com HTTPRFC, o frase de razão pode ser qualquer string personalizada (que esteja em conformidade com o padrão), mas por uma questão de compatibilidade do cliente eu não recomendo colocar uma string aleatória lá.

Observação: php_sapi_name() requer PHP4.0.1

3º argumento para a função de cabeçalho (PHP >= 4.3)

Obviamente, existem alguns problemas ao usar a primeira variante.O maior deles, eu acho, é que ele é parcialmente analisado pelo PHP ou pelo servidor web e é mal documentado.

Desde 4.3, o header A função possui um terceiro argumento que permite definir o código de resposta de maneira confortável, mas usá-lo exige que o primeiro argumento seja uma string não vazia.Aqui estão duas opções:

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

Eu recomendo o 2º.O primeiro faz funciona em todos os navegadores que testei, mas alguns navegadores menores ou rastreadores da web podem ter problemas com uma linha de cabeçalho que contém apenas dois pontos.O nome do campo de cabeçalho no segundo.É claro que a variante não é padronizada de forma alguma e pode ser modificada, apenas escolhi um nome descritivo.

Função http_response_code (PHP >= 5.4)

O http_response_code() função foi introduzida no PHP 5.4 e tornou as coisas bastante mais fácil.

http_response_code(404);

Isso é tudo.

Compatibilidade

Aqui está uma função que criei quando precisava de compatibilidade abaixo de 5.4, mas queria a funcionalidade do "novo" http_response_code função.Acredito que o PHP 4.3 é mais que suficiente para compatibilidade com versões anteriores, mas 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;
    }
}

Outras dicas

Infelizmente descobri que as soluções apresentadas por @dualed apresentam várias falhas.

  1. Usando substr($sapi_type, 0, 3) == 'cgi' não é suficiente para detectar CGI rápido.Ao usar o PHP-FPM FastCGI Process Manager, php_sapi_name() retorna fpm e não cgi

  2. Fasctcgi e php-fpm expõem outro bug mencionado por @Josh - usando header('X-PHP-Response-Code: 404', true, 404); funciona corretamente em PHP-FPM (FastCGI)

  3. header("HTTP/1.1 404 Not Found"); pode falhar quando o protocolo não for HTTP/1.1 (ou seja,'HTTP/1.0').O protocolo atual deve ser detectado usando $_SERVER['SERVER_PROTOCOL'] (disponível desde PHP 4.1.0

  4. Existem pelo menos 2 casos ao ligar http_response_code() resultar em comportamento inesperado:

    • Quando o PHP encontra um código de resposta HTTP que não entende, o PHP substituirá o código por outro que conhece do mesmo grupo.Por exemplo, "521 Web server is down" é substituído por "500 Internal Server Error".Muitos outros códigos de resposta incomuns de outros grupos 2xx, 3xx, 4xx são tratados desta forma.
    • Em um servidor com php-fpm e nginx a função http_response_code() PODE alterar o código conforme o esperado, mas não a mensagem.Isso pode resultar em um cabeçalho estranho “404 OK”, por exemplo.Este problema também é mencionado no site PHP por um comentário de usuário http://www.php.net/manual/en/function.http-response-code.php#112423

Para sua referência, aqui está a lista completa de códigos de status de resposta HTTP (esta lista inclui códigos dos padrões da Internet IETF, bem como outros RFCs da IETF.Muitos deles NÃO são atualmente suportados pela função PHP http_response_code): http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Você pode testar esse bug facilmente chamando:

http_response_code(521);

O servidor enviará o código de resposta HTTP "500 Internal Server Error", resultando em erros inesperados se você tiver, por exemplo, um aplicativo cliente personalizado chamando seu servidor e esperando alguns códigos HTTP adicionais.


Minha solução (para todas as versões do 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);
}

Conclusão

A implementação de http_response_code() não suporta todos os códigos de resposta HTTP e pode substituir o código de resposta HTTP especificado por outro do mesmo grupo.

A nova função http_response_code() não resolve todos os problemas envolvidos, mas piora as coisas introduzindo novos bugs.

A solução de "compatibilidade" oferecida pelo @dualed não funciona como esperado, pelo menos no PHP-FPM.

As demais soluções oferecidas pela @dualed também apresentam vários bugs.A detecção rápida de CGI não suporta PHP-FPM.O protocolo atual deve ser detectado.

Quaisquer testes e comentários são apreciados.

desde o PHP 5.4 você pode usar http_response_code() para obter e definir o código de status do cabeçalho.

aqui um exemplo:

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

aqui está o documento desta função no php.net:

http_código_de_resposta

Adicione esta linha antes de qualquer saída do corpo, caso você não esteja usando buffer de saída.

header("HTTP/1.1 200 OK");

Substitua a parte da mensagem ('OK') pela mensagem apropriada e o código de status pelo seu código conforme apropriado (404, 501, etc.)

Se você está aqui por causa do Wordpress dando 404 ao carregar o ambiente, isso deve resolver o problema:

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

O problema é devido ao envio de um Status:Cabeçalho 404 não encontrado.Você tem que substituir isso.Isso também funcionará:

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

com o Função de cabeçalho .Há um exemplo na seção no primeiro parâmetro que é preciso.

Se a sua versão do PHP não inclui esta função:

<?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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top