PHP header() вызывает "сбой" скрипт с ошибкой HTTP 500

Я использую PHP 5.2.9.

Чтобы увидеть / записать ошибки, в начале моего скрипта у меня есть:

error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'On');
ini_set('log_errors', 'On');
ini_set('error_log', $_SERVER['DOCUMENT_ROOT'] . '/php.log');

Но когда я использую первую из следующих двух строк, мой скрипт выдает ошибку HTTP 500, и ничего не отображается (кроме ошибки 500), и в моем php.log ничего не регистрируется. Если я использую вторую строку вместо первой, все в порядке, и 304 выдается нормально.

header('Not Modified', true, 304); //Crash php with 500 error
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', true, 304); //Works OK
//In both case exit(); is called just after header().

Разве эти две строки не эквивалентны (см. Ссылку ниже)? Почему первая версия "вылетает" из моего скрипта?!

Это связано с: использование заголовка в PHP

Редактировать 1: Это единственный журнал, который я могу найти:

'
69.70.84.xx - - [20/Jan/2010:15:54:06 -0600] "GET /framework2/ HTTP/1.1" 200 2968 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:08 -0600] "GET /foo/bar.js HTTP/1.1" 404 8642 "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:10 -0600] "GET /framework2/ HTTP/1.1" 500 8511 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/mydomain_ajax-dom.js HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Reset.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Error.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Base.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /images/Error-48.png HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
'
  1. Строка 1 - документ, который правильно подан.
  2. Строка 2 - это 404 фиктивного.js в моем документе.
  3. В строке 3 происходит фактическая ошибка (я нажимаю кнопку Обновить в моем браузере, и мой PHP выдает заголовок 304, который приводит к сбою моего скрипта).
  4. Строки 4, 5, 6, 7, 8 вызваны моим пользовательским сообщением об ошибке (через.htaccess), в котором отображается сообщение об ошибке 500.

Изменить 2: Я связался со службой поддержки веб-хостинга, чтобы спросить, есть ли у меня доступ к большему количеству журналов, которые они сказали нет, но с их стороны у них есть доступ к журналам, которые я не вижу. Моя ошибка была там:

'backend: malformed header from script. Bad header=Not Modified: index.php'

Итак, вернемся к моему вопросу... Почему на некоторых хостах первая версия не работает, а на других, кажется, все в порядке (еще хуже, кто-то в ссылке выше говорит, что вторая вылетает, а первая в порядке)??

2 ответа

Решение

Нет, эти строки не эквивалентны. Первый напишет неверную строку заголовка. Документация к header функция говорит:

header() используется для отправки необработанного HTTP-заголовка.

И в описании строкового параметра:

Есть два вызова заголовка специального случая. Первый - это заголовок, который начинается со строки "HTTP/" (регистр не имеет значения), который будет использоваться для определения кода состояния HTTP для отправки.

В вашем случае значение Not Modified не начинается с HTTP/ и, таким образом, обрабатывается не для установки кода состояния HTTP, а только для обычного поля заголовка. Но это неверно, так как не имеет формы:

message-header = field-name ":" [ field-value ]

И это то, что говорится в записи журнала ошибок. Not Modified не является допустимым необработанным HTTP-заголовком.

Третий параметр http_response_code - просто установить код состояния при установке перенаправления, чтобы избежать двух header звонки как:

header('HTTP/1.1 301 Moved Permanently');
header('Location: http://example.com');

Вместо этого вы можете просто написать:

header('Location: http://example.com', true, 301);

Вы хотите проверить журнал ошибок вашего веб-сервера, а не журнал ошибок PHP в этом случае, чтобы получить больше информации о сбое.

Другие вопросы по тегам