PHP: HTTP yanıt kodu nasıl gönderilir?


Yanıtlar:


461

Bu soruyu yeni buldum ve daha kapsamlı bir cevaba ihtiyacı olduğunu düşündüm:

İtibariyle PHP 5.4 Bunu gerçekleştirmek için üç yöntem vardır:

Yanıt kodunu kendiniz bir araya getirme (PHP> = 4.0)

header()İşlevi, bir HTTP yanıt hattını algılar ve özel biriyle Yenisini sağlar özel kullanım senaryosunu vardır

header("HTTP/1.1 200 OK");

Ancak, bu (Hızlı) CGI PHP için özel tedavi gerektirir:

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

Not: göre HTTP RFC , nedeni ifade , ancak istemci uyumluluğu uğruna ben (standardına uygundur o) Herhangi özel bir dize olabilir yok orada rastgele bir dize koyarak önerilir.

Not: PHP 4.0.1php_sapi_name() gerektirir

Üstbilgi işlevine 3. bağımsız değişken (PHP> = 4.3)

İlk değişkeni kullanırken açıkçası birkaç sorun vardır. En büyük ben kısmen PHP veya web sunucusu tarafından ayrıştırılmış ve kötü belgelenmiş olduğunu düşünüyorum.

4.3'ten beri, headerişlevin yanıt kodunu biraz rahat bir şekilde ayarlamanıza izin veren 3. bir bağımsız değişkeni vardır, ancak bunu kullanmak için ilk bağımsız değişkenin boş olmayan bir dize olması gerekir. İşte iki seçenek:

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

Ben ikincisini tavsiye ederim . İlk yapar ben test ettik tüm tarayıcılarda çalışması, ancak bazı küçük tarayıcıları veya web tarayıcıları yalnızca iki nokta üst üste içeren bir başlık satırından ile ilgili bir sorun olabilir. İkinci alandaki başlık alanı adı. varyant elbette herhangi bir şekilde standartlaştırılmamış ve değiştirilebiliyordu, sadece umarım açıklayıcı bir isim seçtim.

http_response_code işlevi (PHP> = 5.4)

http_response_code()Fonksiyon PHP 5.4 tanıtıldı ve o şeyler yapılmış çok daha kolay.

http_response_code(404);

Bu kadar.

uygunluk

İşte 5.4 altında uyumluluk gerektiğinde pişirdiğim ama "yeni" http_response_codefonksiyonun işlevselliğini istediğim bir fonksiyon. Ben PHP 4.3 fazlasıyla geriye dönük uyumluluk olduğuna inanıyorum, ama asla bilemezsiniz ...

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

10
Bunu teyit edebilir header('X-PHP-Response-Code: 404', true, 404);düzgün altında çalışır PHP-FPM (FastCGI)
Josh

@dualed (1) aradıktan headers_sent()hemen sonra her zaman doğru olmaz mıydı header()? (2) 5.4 dünyasında hiç http_response_text () gibi bir şey buldunuz mu? En azından eski başlık () durum kodundan sonraki metni etkileyebilir.
Bob Stein

@ BobStein-VisiBone (1) headers_sent() , başlık eklediyseniz içerik zaten gönderildiğinden başka başlık ekleyemiyorsanız doğrudur. (2) Üzgünüm, hayır. Diğer dillerde de daha iyi destek var
dualed

1
@ Bunu önermememin sebebi, yalnızca iki nokta üst üste olanını önermememin aynısı. PHP böyle bir "üstbilgi" ile ne olacağını tanımlanmadığı için bunu farklı şekillerde işleyebilir, tamamen başarısız olabilir - üstbilgi veya durum ayarlanamaz veya geçersiz bir üstbilgi eklenebilir (http 1.1 protokol standardı iki nokta üst üste işaretini gerektirir )
Şubat'ta ikili

8
Saatlerce harcadım http_response_code(ve daha genel olarak başlığı değiştirmenin) bir echoşeyden sonra artık işe yaramadığını fark ettim . Umarım yardımcı olur.
Neptilo

40

Ne yazık ki @dualed tarafından sunulan çözümlerin çeşitli kusurları olduğunu buldum.

  1. substr($sapi_type, 0, 3) == 'cgi'Hızlı CGI algılamak için kullanmak yeterli değildir. PHP-FPM FastCGI Process Manager kullanırken php_sapi_name()cgi değil fpm döndürür

  2. Fasctcgi ve php-fpm, @Josh tarafından belirtilen başka bir hatayı ortaya çıkarır - header('X-PHP-Response-Code: 404', true, 404);PHP-FPM (FastCGI) altında kullanma düzgün çalışır

  3. header("HTTP/1.1 404 Not Found");protokol HTTP / 1.1 olmadığında başarısız olabilir (yani 'HTTP / 1.0'). Mevcut protokol kullanılarak tespit edilmelidir $_SERVER['SERVER_PROTOCOL'](PHP 4.1.0'dan beri mevcuttur)

  4. http_response_code()Beklenmedik davranışla sonuçlanırken en az 2 durum vardır :

    • PHP anlamadığı bir HTTP yanıt kodu ile karşılaştığında, PHP kodu aynı gruptan bildiği kodla değiştirecektir. Örneğin, "521 Web sunucusu kapalı" ifadesi "500 Dahili Sunucu Hatası" ile değiştirilir. Diğer gruplardan 2xx, 3xx, 4xx diğer pek çok nadir yanıt kodu bu şekilde işlenir.
    • Php-fpm ve nginx http_response_code () işlevine sahip bir sunucuda kodu beklendiği gibi değiştirebilir, ancak iletiyi değiştiremez. Bu, örneğin garip bir "404 OK" başlığına neden olabilir. Bu sorun PHP web sitesinde bir kullanıcı yorumu tarafından da belirtilmiştir http://www.php.net/manual/en/function.http-response-code.php#112423

Burada referansınız için HTTP yanıt durum kodlarının tam listesi vardır (bu liste, IETF internet standartlarının yanı sıra diğer IETF RFC'lerinden kodları içerir. Birçoğu şu anda PHP http_response_code işlevi tarafından desteklenmemektedir): http: //en.wikipedia .org / wiki / List_of_HTTP_status_codes

Bu hatayı arayarak kolayca test edebilirsiniz:

http_response_code(521);

Örneğin sunucunuzu çağıran ve bazı ek HTTP kodları bekleyen özel bir istemci uygulamanız varsa, sunucu "500 Dahili Sunucu Hatası" HTTP yanıt kodu gönderir.


Benim çözümüm (4.1.0'dan beri tüm PHP sürümleri için):

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

Sonuç

http_response_code () uygulaması tüm HTTP yanıt kodlarını desteklemez ve belirtilen HTTP yanıt kodunun üzerine aynı gruptan başka bir kod yazabilir.

Yeni http_response_code () işlevi, tüm sorunları çözmez, ancak yeni hatalar getirmeyi en kötü hale getirir.

@Dualed tarafından sunulan "uyumluluk" çözümü en azından PHP-FPM altında beklendiği gibi çalışmaz.

@Dualed tarafından sunulan diğer çözümlerin de çeşitli hataları vardır. Hızlı CGI algılaması PHP-FPM'yi işlemez. Mevcut protokol tespit edilmelidir.

Herhangi bir test ve yorum takdir edilmektedir.


21

PHP 5.4'ten beri kullanabilirsiniz http_response_code() get ve set başlık durumu kodunu kullanabilirsiniz.

burada bir örnek:

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

İşte php.net bu işlevi belge:

http_yanıt_kodu


Deneyimlerime göre, bu en iyi cevap.
Scruffy

Neden var_dump () kullanılır?
Tomas Gonzalez

Ama neden yankı yerine var_dump ()? Sonuç basit bir yankı için uygun olmayabilir mi? Veya print_r (). var_dump () üretim kodu için yeterli görünmüyor ...
Tomas Gonzalez

@TomasGonzalez büyük bir anlaşma değil, ben sadece var_dump () ile her şeyi yazdırarak u içinde ne göstermek istedim ve doğru değil r önemli değil
Seyed Ali Roshan

Tamam anladım. Dikkatimi çeken şey, resmi dokümanlarda, örneğin var_dump () kullanmasıdır. Bu yüzden bunun nedenini merak ettim. Kaçırdığım bir şey olabilirdi. php.net/manual/tr/function.http-response-code.php
Tomas Gonzalez

10

Çıktı tamponlama kullanmıyorsanız, bu satırı gövdenin herhangi bir çıktısından önce ekleyin.

header("HTTP/1.1 200 OK");

İleti bölümünü ('Tamam') uygun iletiyle ve durum kodunu uygun şekilde kodunuzla (404, 501, vb.) Değiştirin.


2
Verdiğimiz mesaj (Tamam'ı düzeltmek için) herhangi bir şey olabilir mi?
FMaz008

Bu benim için çalıştı. PHP 5.3 ile bir web sitesinde bir iletişim formu üzerinde çalışıyordu. Ve bu çözüm benim için çalıştı. AJAX isteği başarısız işlevi için yanıt metni ve bu HTTP kodu verecektir. Tüm istediğim bu.
Surjith SM

7

Wordpress ortamı yüklerken 404'lerden dolayı buradaysanız, bu sorunu çözmelidir:

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

Sorun bir Durum göndermesinden kaynaklanıyor: 404 Bulunamadı başlığı. Bunu geçersiz kılmalısın. Bu ayrıca işe yarayacaktır:

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

başlık ("HTTP / 1.1 200 OK"); http_yanıt_kodu (201); başlık ("Durum: 200 Tüm pembe"); // iş
alpc



2

PHP sürümünüz bu işlevi içermiyorsa:

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

1

İki farklı ortam üzerinden http_response_code'dan farklı bir dönüş değeri alabiliriz:

  1. Web Sunucusu Ortamı
  2. CLI ortamı

Web sunucusu ortamında, bir yanıt kodu verdiyseniz veya herhangi bir yanıt kodu girmediğinizde önceki yanıt kodunu döndürün, o zaman geçerli değeri yazdırır. Varsayılan değer 200'dür (Tamam).

CLI Ortamı'nda, bir yanıt kodu sağladıysanız true döndürür ve herhangi bir yanıt_ kodu sağlamazsanız false olur.

Response_code'un dönüş değeri Web Sunucusu Ortamı örneği:

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

Response_code'un dönüş değerinin CLI Ortamı örneği:

var_dump(http_response_code()); // bool(false)
var_dump(http_response_code(501)); // bool(true)
var_dump(http_response_code()); // int(501)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.