PHP Üstbilgi kullanımı

6 Cevap php

Oldukça basit bir soru: Bu iki PHP (sürüm 5 +) başlık çağrısının bir "en iyi" nedir?

header('Not Modified', true, 304);
header('HTTP/1.1 304 Not Modified');

Ben ilk en değerlikli biridir eminim, ama sadece merak eğer PHP HTTP 1.0 altında ikinci bir "düzeltme" olsaydı ...

Teşekkürler!

Edit: One of these header crashes PHP on my Web host. Follow-up question at: http://stackoverflow.com/questions/2104655/php-header-call-crashing-script-with-http-500-error

6 Cevap

Ben bunu kullanmak:

header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified', true, 304);

$_SERVER['SERVER_PROTOCOL'] contains the protocol used in the request like HTTP/1.0 ya da HTTP/1.1.


Edit Benim önerim anlamsız olduğunu itiraf etmeliyim. Birkaç denemeden sonra ben ilk parametresi geçerli ise ikinci durum kodu, üçüncü parametre ile verildi eğer ve ne HTTP status line, PHP ne olursa olsun bu durum hattını kullanacağını fark ettim. Birden fazla durum satır olamaz Ve ikinci parametre (belgeleme isimler replace) da işe yaramaz.

Yani bu çağrı, ikinci ve üçüncü parametre sadece gereksizdir:

header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified', true, 304);

Sadece bu kullanmak yerine:

header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');

Işaret değer ilk başlık arama davranışı hakkında iki şey vardır:

  • Eğer 3. argüman sağlamak, PHP, ilk dize argümanı görmezden ve verilen numara için doğru yanıtı gönderir. Bu programcı hataları ilk yöntem daha az eğilimli hale getirebilir.
  • PHP isteği HTTP/1.0 ile yapıldığı zaman bile bir HTTP/1.1 yanıt ile görünüyor

Http yanıt kodu argümanı sadece> = PHP 4.3.0 (kod taşınabilirliği etkileyebilecek) desteklenir gibi, ikinci bir ile gitmek istiyorum.

Bunu birçok kez yaptım ve bir özel durum olmadığı sürece ben hiç bir sorun olacağını sanmıyorum bu yüzden, HTTP/1.1 desteklemeyen herhangi bir istemci rastlamak ettik.

Ben normalde ikinci örnek ile devam ediyorum - ancak, son zamanlarda apachebench kullanarak uygulama kıyaslama yaparken, biz ab sık sık asılı fark ettim.

Hata ayıklama sonra, tespit edilmiştir ki bu tarzda başlık:

header('HTTP/1.1 304 Not Modified')

Suçlu (Evet, hiçbir fikrim yok) ve değiştirdikten sonra oldu

header('Not Modified', true, 304);

İster inanın ister ab çalışmaya başladı değil. Çok garip ama düşünmek bir şey. Herhalde ileriye ikinci yöntemi kullanacağız.

İleride başvurmak için http_yanıt_kodu () işlevi 5.4 geliyor:

http://www.php.net/manual/en/function.http-response-code.php

Bir alternatiftir:

if (!function_exists('http_response_code')) {
    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;

    }
}

Bu örnekte ben $ GLOBALS kullanıyorum, ama sen istersen depolama mekanizması kullanabilirsiniz ... Ben mevcut durum kodu dönmek için bir yol var sanmıyorum:

https://bugs.php.net/bug.php?id=52555

Referans için hata kodları PHP'nin kaynak kodu var:

http://lxr.php.net/opengrok/xref/PHP_5_4/sapi/cgi/cgi_main.c#354

Ve nasıl geçerli http başlık kullandığı değişkenler, gönderilir:

http://lxr.php.net/opengrok/xref/PHP_5_4/main/SAPI.c#856

Ben Gumbo cevabı şimdiye kadar en mantıklı olduğunu düşünüyorum. Ancak bu deneyin:

<?php
header('Gobbledy Gook', true, 304);
?>

İlk dize uygun bir başlık değilse atılır. Iy o başlıklarına eklenir geçerli başlığına benziyor - bu deneyin:

<?php
header('Cache-Control: max-age=10', true, 304);
?>

Başlığı için manuel () ve özel durumlarda dikkat - genel olarak böyle yerleşik buluşsal güvenmek onun tavsiye sanmıyorum.

Ancak, ben tahmin ediyorum ki senin vekillerinin / tarayıcılar tarafından iyi önbelleğe içerik almak gerçekten ilgilenen. Çoğu durumda, gecikme bant genişliği daha bir sorun bir sorun çok fazla. Sonraki önbelleğe içerik bayat bir tarayıcı nasıl davranacağını düşünün - güncelleme önbelleğe bilginin yokluğunda, içeriği hala bayat olup olmadığını görmek için sunucuya tekrarlanan istekleri yapma tutar.

Yani çoğu durumda istekleri (hatta daha iyi webserver onları sıyırma) koşullu bölümünü yok sayarak aslında performansını geliştirir.