Сценарий в листинге 24.4 приводит к кэшированию страницы на протяжении 24 часов. Как и в листинге 24.3, заголовки Last-Modified, Expires и Cache-Control используются для управления поведением кэш-памяти. Время последней модификации отправляется как настоящее время модификации файла. Срок хранения задается равным 24 часам, начиная с текущего времени. А кэш-память знает, что время существования равно 86400 секундам, или количеству секунд в сутках. Для того чтобы убедиться в том, что файл выбирается из кэш-памяти, попробуйте быстро перезагрузить страницу. Даты на странице должны оставаться прежними.
Листинг 24.4. Отправка заголовков для инициализации кэширования

<?php
// сообщить реальное время изменения сценария
$LastModified = filemtime(_FILE_) + date("Z");
header("Last-Modified: " .
gmdate("D, d M Y H:i:s", $LastModified) . " GMT");
//задать срок хранения, равным 24 часам (86400 секундам), начиная с текущего момента
$Expires = time() + 86400;
header("Expires: " .
gmdate("D, d M Y H:i:s", $Expires) . " GMT");
//сообщить кэш-памяти о возможности существования 24 часа (86400 секунд)
header("Cache-Control: max-age=86400");
?>
<html> <head>
^^^хЛистинг 24.4</title>
</head>
<body>
Текущее время <?php print(gmdate("D, d M Y H:i:s")); ?> GMT<br> <br>
В последний раз этот документ был модифицирован
<?php print(gmdate("D, d M Y H:i:s", $LastModified)); ?> GMT<br> Срок хранения в кэш-памяти
<?php print(gmdate("D, d M Y H:i:s", $Expires)); ?> GMT<br>
</body>
</html>

Следует заметить, что во всех датах в этих двух примерах используется время по Гринвичу. Это определяется протоколом HTTP. Если не преобразовать время местного часового пояса во время по Гринвичу, это повлечет за собой бесчисленное количество ошибок.
24.3. Установка типа документа
По умолчанию PHP отправляет HTTP-заголовок, определяя документ как HTML-документ. Заголовок Content-Type задает тип MIME text/html, и браузер интерпретирует код как HTML-код. Иногда может появиться необходимость создать с помощью PHP документы других типов. В главе 25, "Создание графических изображений", освещается тема создания изображений, для чего может потребоваться ис­пользование содержимого image/png. Типы MIME координируются агентством по выделению имен и уникальных параметров протоколов Internet (Internet Assigned Numbers Authority, IANA). Официальный перечень типов представлен на Web-странице по адресу <http://www.isi.edu/in-notes/iana/assignments/media-types/>.
Иногда можно извлечь выгоду из реакции браузеров на различные типы содержимого. Например, тип text/plain отображается шрифтами постоянной длины, без какой-либо интерпретации HTML-кода. При использовании в качестве типа содержимого */* браузер отображает диалоговое окно, предназначенное для сохранения файлов. Вероятно, наиболее интересным использованием является запуск вспомогательных приложений.
В листинге 24.5 показано, что создается текстовый файл, разделенный символами табуляции, позволяющий запустить программу Microsoft Excel. При этом необходимо принимать во внимание то, что компьютер должен соответствовать определенным тре­бованиям. Прежде всего, он должен работать под управлением Windows, с установленной программой Microsoft Excel. Более новые версии Excel ассоциируют тип содержимого application/vnd.ms-excel с файлами .xls. Мой опыт показывает, что эти заголовки генерируют OLE-контейнер Excel в браузерах MSIE или Netscape Navigator на машине под управлением Windows, но ваш опыт может свидетельствовать о другом. Другие браузеры могут запрашивать пользователя о необходимости сохранения файла.
Вторым заголовком в листинге 24.5 является Content-Disposition. Он не входит в стандартный протокол HTTP 1.1, но большинство браузеров распознает его. Он позволяет задавать имя файла. При добавлении к заголовку "attachment;" браузер открывает Excel в отдельном окне.

| Листинг 24.5. Отправка Excel-файла в формате разделения символами табуляции
<?php
// задать тип документа
header("Content-Type: application/vnd.ms-excel"); header("Content-Disposition: filename="listing24-5.txt""); //отправить какие-либо данные, разделенные символами табуляции print("Листинг 24.5rn"); for($i=1; $i < 100;
{
print("$it"); print(($i * $i) . "t"); print(($i * $i * $i) . "rn");
}
?>