2010-01-04 3 views
4

Довольно простой вопрос: какой из этих двух заголовков заголовков PHP (версия 5+) является «лучшим»?Использование заголовка в PHP

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

Я довольно уверен, что первый из них является наиболее поливалентных один, но просто интересно, если PHP будет «исправить» второй, если под HTTP 1,0 ...

Спасибо!

Редактировать: Один из этих заголовков разбивает PHP на моем веб-хосте. Последующий вопрос: PHP header() call "crashing" script with HTTP 500 error

ответ

8

Я хотел бы использовать этот один:

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

$_SERVER['SERVER_PROTOCOL'] содержит протокол, используемый в запросе, как HTTP/1.0 или HTTP/1.1.


Edit Я должен признать, что мое предложение бессмысленно. После нескольких тестов я заметил, что если первый параметр является допустимым HTTP status line, PHP будет использовать эту строку состояния независимо от того, был ли и какой второй код состояния указан третьим параметром. И второй параметр (документация называет его заменить) тоже бесполезен, поскольку не может быть нескольких строк состояния.

Так второй и третий параметр в этом вызове просто лишний:

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

Используйте только вместо этого:

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

Я бы пошел со вторым, поскольку аргумент кода ответа HTTP поддерживается только> = PHP 4.3.0 (что может повлиять на переносимость кода).

Я делал это много раз и не сталкивался с любым клиентом, который не поддерживает HTTP/1.1, поэтому, если у вас нет специального случая, я не должен думать, что это будет проблемой.

+2

почему вы заботитесь о совместимости php4? не используете ли вы объекты (или используете их очень ограниченно)? –

+2

Действительно, я считаю, что PHP 4 холодный мертв. Я больше не поддерживаю PHP <5 в любом из моих сценариев. – AlexV

+0

Довольно, но по-прежнему существует большое количество серверов PHP 4, поэтому, если потребуется, чтобы код был переносимым, то это соображение. Почему вы все еще заботитесь об HTTP/1.0? –

4

Есть две вещи, о поведении первого вызова заголовка, которые стоит отметить:

  • Если вы предоставите 3-й аргумент, PHP будет игнорировать первый строковый аргумент и отправить правильный ответ на заданный номер. Это может сделать первый метод менее подверженным ошибкам программиста.
  • PHP кажется реагировать с HTTP/1.1 ответа, даже если запрос был сделан с HTTP/1.0
+0

Кажется, что первая точка не соответствует действительности (по крайней мере, для моего веб-хостинга), поскольку я получаю «backend: неправильный заголовок из сценария».Bad header = Not Modified: index.php "... – AlexV

2

я обычно иду со вторым примером - однако, когда в последнее время тестирования приложения с помощью ApacheBench, мы заметили, ab висит часто.

После отладки, было установлено, что заголовок в этом стиле:

header('HTTP/1.1 304 Not Modified') 

был виновником (Да, я понятия не имею) и после изменения его,

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

Верьте или не начал работать. Очень странно, но о чем подумать. Вероятно, я буду использовать второй метод в будущем.

+0

Strange ... Мой хост с ошибкой 500 при использовании заголовка ('Not Modified', true, 304); (я получаю ошибку" backend: неправильный заголовок из скрипта Bad header = Not Modified: index.php "). – AlexV

1

Я думаю, что ответ Гамбо является наиболее разумным до сих пор. Однако попробуйте это:

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

Если первая строка не является надлежащим заголовком, она отбрасывается. Если гу выглядит как действительный заголовок он приложенный к коллекторам - попробуйте это:

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

Руководство для заголовка() и обратите внимание на особых случаи - в общем, я думаю, его не рекомендуется полагаться на таких встроенном в эвристике.

Тем не менее, я предполагаю, что на самом деле вы заинтересованы в том, чтобы контент был хорошо кэширован прокси/браузерами. В большинстве случаев латентность - это скорее проблема проблемы, чем пропускная способность. Далее рассмотрите, как работает браузер, когда кешированный контент устарел - в отсутствие обновленной информации кэширования он продолжает повторять запросы на сервер, чтобы узнать, все ли содержимое остается устаревшим.

I.e. в большинстве случаев игнорирование условной части запросов (или даже лучшее удаление их на веб-сервере) фактически повышает производительность.

+0

« Если первая строка не является надлежащим заголовком, она отбрасывается. Если я действительно выгляжу как допустимый заголовок, он добавляется к заголовкам «вы уверены в этом? Когда я использую заголовок (« Не изменено »,« Истина », 304), я получаю ошибку« Бэкэнд: неправильный заголовок из сценария ». Bad header = Not Modified: index.php «это из-за этого? – AlexV

2

Для дальнейшего использования функции http_response_code() приходит в 5.4:

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

Альтернатива:

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; 

    } 
} 

В этом примере я использую $ GLOBALS, но вы можете использовать какой механизм хранения вам нравится ... Я не думаю, что есть способ вернуть текущий код состояния:

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

Для справки коды ошибок, которые я получил из исходного кода РНР:

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

А как текущий заголовок HTTP отправляется, с переменными, которые он использует:

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