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 - документ, который правильно подан.
- Строка 2 - это 404 фиктивного.js в моем документе.
- В строке 3 происходит фактическая ошибка (я нажимаю кнопку Обновить в моем браузере, и мой PHP выдает заголовок 304, который приводит к сбою моего скрипта).
- Строки 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 в этом случае, чтобы получить больше информации о сбое.