LINUX.ORG.RU

Как работает header()?

 


0

2

header — Отправка HTTP-заголовка.

Если что-то вывести до заголовков, то будет что-то типа «заголовки уже отправлены». Поэтому и возник вопрос.

Какое понимание верное? Сам склоняюсь ко второму.

  1. Сценарий выполняет header(…) и отправляет заголовок в браузер. Если после header(…) идет опять header(…), то он опять обрабатывается и отправляет браузеру. Браузер получается получает каждый заголовок отдельно. После заголовков сценарий отправляет тело в браузер.

  2. Сценарий выполняет каждый header(…), запоминает сформированные заголовки. В конце добавляет тело. Отправляет и заголовки и тело разом.


Ответ на: комментарий от VolanQ

А как браузер понимает когда конец ответа?

В принципе - просто по концу TCP-соединения (или TLS-соединения, если используется HTTPS). Ну т. е. веб-обозреватель как бы читает «файл» ответа и при запросе очередной порции получает «конец данных». Еще есть HTTP-заголовок Content-Length, который можно использовать для дополнительного контроля, если длина отправляемого ответа известна заранее. Сейчас еще в ходу HTTP2 - там данные упаковываются в соединение похитрее, поскольку одно TLS-соединение используется для обслуживания нескольких HTTP-запросов.

vinvlad ★★
()
Последнее исправление: vinvlad (всего исправлений: 1)
Ответ на: комментарий от VolanQ

Да, php://output это и есть выходной поток. Можно ли через него слать header я точно не знаю. По логике - должно быть можно, но в реальности может вывод в него как раз и начинается с «\r\n\r\n», так что нужно проверять. С точки зрения Web-сервера, в общем, тело ответа и заголовки ответа - это один и тот же поток вывода

r0ck3r ★★★★★
()
Ответ на: комментарий от VolanQ

А выходной поток это php://output и туда же заголовки уходят, верно?

В документации сказано:

php://output is a write-only stream that allows you to write to the output buffer mechanism in the same way as print and echo.

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

Почитай спецификацию CGI и FastCGI - там описывается процедура взаимодействия веб-сервера и PHP.

vinvlad ★★
()
Последнее исправление: vinvlad (всего исправлений: 1)
Ответ на: комментарий от vinvlad

А когда результат запроса браузер получает порциями, то сначала сервер отправляет условно

Заголовок 1
Заголовок 2

Первая строка тела ответа

потом

Заголовок 1
Заголовок 2

Первая строка тела ответа
Вторая строка тела ответа

т.е каждый раз отличается только тело?

Или следующий подход используется?:

Заголовок 1
Заголовок 2

Первая строка тела ответа

потом

Вторая строка тела ответа

Т.е браузер после первого раза получает только тело кусками.

VolanQ
() автор топика
Ответ на: комментарий от VolanQ

А когда результат запроса браузер получает порциями, то сначала сервер отправляет условно …

Нет конечно. Веб-клиент получает один цельный ответ, оформленный в соответствии с требованиями HTTP-протокола. Просто веб-клиент может получать данные одного конкретного HTTP-ответа порциями, так же, как если бы он читал эти данные из файла. Если, например, веб-клиент скачивает какой-то файл очень большого размера, то он уже может получить строку HTTP-статуса, HTTP-заголовки и начальную часть HTTP-тела, а PHP-шный код в это время будет еще доотправлять хвостовую чаcть файла.

Почитайте спецификацию протокола HTTP - без этого просто не имеет смысла заниматься веб-программированием. Ну и вам надо поиметь представление о том, как выполняется обмен данными между клиентом и сервером по сетевому TCP-соединению.

vinvlad ★★
()
Последнее исправление: vinvlad (всего исправлений: 1)

HTTP-Сообщение имеет такой вид:

статус/запрос<crlf>
Заголовок1: Значение1<crlf>
Заголовок2: Значение2<crlf>
...
<crlf>
<crlf>
<html>
...
</html>

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

uwuwuu
()