8.6. HTTP-заголовки
HTTP-заголовки представляют собой специальные команды, пересылаемые между браузером и Web-сервером перед получением сервером какого-либо содержимого. Одни заголовки дают серверу знать, какой файл ожидает браузер, другие уведомляют браузер о типе файла, который будет передан. Для того чтобы узнать больше о заголовках, можно обратиться к спецификации HTTP в документах RFC 1945 и RFC 2616. Эти и другие аналогичные документы можно найти на узле W3C, который имеет раздел, посвященный протоколу HTTP (<http://www.w3.org/Protocols/>). Подробно о работе заголовков с PHP см. в главе 7, "Операции ввода-вывода и доступ к диску". 
boolean header(string http_header, boolean replace, integer response)
Функция header (листинг 8.9) отправляет заголовок HTTP в браузер. Если буферизация вывода, описанная выше в этой главе, не используется, функция header должна вызываться до отправки какого-либо вывода в браузер. Отсылаться могут самые различные виды заголовков. Вероятно, самым популярным является заголовок Location, который переключает браузер на другой URI. При каждом вызове функции header при первой отправке вывода в браузер к списку, сохраняемому в браузере, добавляется HTTP. Заголовки сохраняются в том порядке, в котором они были созданы. Вторичная установка заголовка замещает предыдущее значение, если в необязательном втором аргументе не установлено значение FALSE и в таком случае PHP отправит оба заголовка.
Третий необязательный аргумент устанавливает код HTTP-ответа, возвращаемого сервером.
PHP рассматривает два заголовка отдельно. Первый - когда отправляется заголовок ответа (это первая строка, возвращаемая Web-сервером). PHP обнаруживает ее благодаря поиску подстроки HTTP/ в начале строки, которая передается функции header. PHP всегда сначала отправляет этот заголовок.
Другой особый случай имеет отношение к заголовку Location. PHP меняет код ответа на 302 для соответствия заголовкам Location, если вы не задали вручную для заголовка ответа значение, начинающееся с 3.
Заголовки также используются для отправки файлов cookie, но для этих целей лучше подходит функция PHP setcookie.
Один из обычных фокусов, которые позволяет себе функция header, - это перена­править пользователя на другую страницу (см. листинг 8.9). Другой заключается в загрузке благодаря функции header браузером файла или отображении его в контейнере OLE. Это можно сделать с помощью заголовка Content-type, который по умолчанию равняется text/html. После отправки значения application/octet-stream в большинстве браузеров появится подсказка о том, где нужно сохранять файл. Кроме того, для получения справочной информации можно использовать и другие MIME-типы. Например, при использовании application/vnd.ms-excel машина под управлением Windows с установленным на ней Microsoft Excel запустит последнее в OLE-контейнере в окне браузера, и в таком случае отпадает необходимость пересылать файл Excel. Обычный разделенный символами табуляции файл будет корректно интерпретирован.

| Листинг 8.9. Функция header_
<?php
// перенаправить запрос по другому адресу header("Location: http://www.leonatkinson.com/");
?>

boolean setcookie(string name, string value, integer expire, string path, string domain, integer secure)
Функция setcookie (листинг 8.10) используется для установки файла cookie для браузера. Файлы cookie рассылаются как заголовки при установке HTTP-соеди-нения. Так как заголовки файлов cookie сложнее других заголовков, неплохо иметь в своем распоряжении функцию, предназначенную непосредственно для рассылки файлов cookie. Нужно помнить, что все заголовки должны отсылаться до отправки содержимого. Кроме того, вызов setcookie не создаст переменных PHP до тех пор, пока файл cookie не будут сброшен браузером при следующей загрузке страницы. При вызове функции setcookie с одним только аргументом имени файл cookie будет удален из базы данных файлов cookie браузера. В противном случае файл cookie будет создан в браузере клиента с именем и заданным значением. Необязательный аргумент expire устанавливает время, по истечении которого файл cookie будет автоматически удален браузером. Он задается в секундах, прошедших с 1 января 1970 года. PHP преобразует это время во время по Гринвичу в соответствии с формой заголовка Set-Cookie. Если аргумент expire не задан, браузер удалит файл cookie после завершения сеанса. Обычно это происходит, когда браузер прекращает свою работу.
Аргументы path и domain используются браузером для определения необходимости отсылки файла cookie. Имя узла, на котором располагается Web-сервер, сравнивается с именем домена. Если оно пустое, используется полное имя узла из установок Web-сервера. Путь сравнивается с путем к каталогу документов на сервере. Спецификация файла cookie требует, чтобы в именах доменов имелись две точки. Это предотвращает рассылку сценариев на домены верхнего уровня (.com, .edu, .net), а также появление доменного имени типа leonatkinson.com. Поэтому не забывайте добавлять точку перед именем.
Аргумент secure используется для того, чтобы задать браузеру пересылку файлов cookie только через безопасные соединения, в которых используется Secure Socket Layers. Для обозначения безопасного файла cookie используется значение 1. Заголовки, созданные функцией setcookie, как и другие заголовки, пересылаются в стек. Это является причиной их передачи в обратном порядке. При пересылке файла cookie более одного раза, первый вызов функции setcookie будет выполнен последним. Вернее всего, это не совсем то, что от них требуется. Отслеживайте значение, которое вы хотите задать в качестве значения файла cookie, и вызывайте функцию setcookie один раз.
Компания Netscape, в свое время создавшая файлы cookie, предоставляет детальную информацию о них в документе "Сохранение информации о клиенте: файлы cookie HTTP" (<http://developer.netscape.com/docs/manuals/communicator/ jsguide4/cookies.htm>).
Как можно узнать, что браузер принимает ваши файлы cookie? Единственным способом является отправка файла cookie и проверка его возвращения при следующем обращении к странице.

Листинг 8.10. Функция setcookie

<?php /*
** обозначить этот узел как посещаемый ** на протяжении следующих 24 часов
*/
setcookie("HasVisitedLast24Hours", "Yes", time()+86400);
?>