ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

Разработка отдельных фрагментов сайтов, консультации по вопросам верстки веб-страниц и веб-программирования.

Протокол HTML. Функции для работы с HTTP-заголовками

Протокол HTML

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

Примечание. Все стандарты в сети Иртернет оформляются в виде RFC-документов; так протокол HTTP описывается главным образом в RFC2616. Ссылки на него можно получить при помощи любой любой поисковой системы.

Работа протокола HTTP не сводится только к передаче сервером HTML-документа по запросу клиента. Помимо HTML-документа, файла или изображения браузер и сервер обмениваются HTTP-заголовками, через которые клиент может сообщить о своих предпочтениях, типе и версии браузера и операционной системы. Сервер, в свою очередь, может сообщить клиенту об ошибочном запросе, "попросить" его установить cookie и т.п. Язык разметки HTML и серверный язык РНР разрабатывались таким образом, чтобы разработчик мог работать без знания HTTP — это позволит отделить уровни протокола и веб-приложения друг от друга. Тем не менее, совершенно абстрагироваться от протокола HTTP не удается, так как его использование зачастую позволяет более гибко управлять работой веб-приложения. В связи с этим в РНР введено несколько инструментов управления протоколом HTTP, которые будут обсуждаться далее в этом разделе:

  • функции для работы с HTTP-заголовками;
  • функции для установки сессий и cookie;
  • сокеты;
  • библиотека CURL.

Помимо этого, будет рассмотрен смежный вопрос преобразования IP-адресов и доменных имен.

Функции для работы с HTTP-заголовками

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

Примечание. HTTP-документ может не содержать тела документа, но всегда содержит HTTP-заголовки.

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

Для управления HTTP-заголовками в РНР предназначены функции, представленные в таблице.

Таблица. Функции для управления HTTP-заголовками
Функция Описание
header() Отправляет HTTP-заголовок
headers_list() Возвращает список отправленных или готовых к отправке HTTP-заголовков
headers_sent() Проверяет отправлены ли HTTP-заголовки

Функция header(), позволяющая отправить клиенту произвольный HTTP-заголовок, имеет следующий синтаксис:

header ($header [, $replace [, $http_response_code]])

Данная функция отправляет HTTP-заголовок $header. Второй параметр $replace определяет поведение интерпретатора РНР, если тот встречает два одинаковых заголовка: если параметр принимает значение true, отправляется последний заголовок, в противном случае — отправляется первый заголовок. Третий параметр $http_response_code позволяет задать код возврата HTTP.

Простейшей процедурой, которую можно осуществить при помощи функции header(), является переадресация, осуществляемая при помощи HTTP-заголовка Location.

Примечание. Вместо полного сетевого адреса (начинающегося с префикса http://) можно использовать относительные адреса: в этом случае браузер сам подставит адрес сайта.

Переадресация при помощи HTTP-заголовка Location
<?php
header("Location: http://rambler.ru");
?>

Механизм HTTP-заголовков дублирован в языке разметки HTTP и добиться схожего поведения можно при помощи передачи HTTP-заголовка через META-тег.

Переадресация средствами HTML
<META http-equiv="refresh" content="0; URL=http://rambler.ru">

Если в качестве второго параметра передать функции header() значение true, то все предыдущие HTTP-заголовки с таким же именем будут заменяться последующими.

Переадресация на сайт http://sevidi.ru
<?php
header("Location: http://www.softtime.ru", true);
header("Location: http://sevidi.ru", true);
?>

На каждый запрос клиента сервер может возвращать HTTP-код состояния, отражающий вид переадресации при окончательном или временном перемещении документа. Если документ найден и успешно отправлен клиенту, в HTTP-заголовки помещается код состояния 200; если документ не найден — 404; в случае переадресации, клиенту отправляется код состояния 302 — "ресурс временно перемещен". Иногда бывает полезно изменить код состояния на 301 — "ресурс перемещен постоянно".

Изменение состояния кода
<?php
header("Location: http://sevidi.narod.ru", true);
header ("HTTP/1.1 301 Moved Remanently");
?>

Коды состояния разделяются на классы, каждый из которых начинается с новой сотни:

  • 100—199 — информационные коды состояния, сообщающие клиенту, что сервер пребывает в процессе обработки запроса. Реакция клиента на данные коды не требуется;
  • 200—299 — коды успешного выполнения запроса. Получение данного кода ответа на запрос означает, что запрос успешно выполнен и в теле присланного документа находится запрашиваемый документ, который можно передать пользователю;
  • 300—399 — коды переадресации, предназначенные для уведомления клиента о том, что для завершения запроса необходимо выполнить дальнейшие действия (как правило, перейти по новому адресу);
  • 400—499 — коды ошибочного запроса, отправляемые клиенту, если сервер не может обработать его запрос;
  • 500—599 — коды ошибок сервера, возникающих по вине сервера (как правило, из-за синтаксической ошибки в файле .htaccess).

Не все коды состояния имеют смысл; часть из них зарезервирована для дальнейших расширений. В таблицах ниже, описываются коды состояния для протокола HTTP 1.1, используемого в настоящее время для распространения HTTP-страниц в сети Интернет.

Таблица. Информационные HTTP-коды состояния
HTTP-код Описание
100 Continue Сервер готов получить оставшуюся часть запроса
101 Switching Protocols Сервер готов переключить протокол приложения на протокол, указанный в заголовке запроса Upgrade, предоставленного клиентом. Переключение должно выполняться, только если указанный протокол имеет преимущество над старым, например, клиент может отправить запрос, чтобы сервер использовал вместо текущего более новый протокол HTTP
Таблица. HTTP-коды успешного выполнения запроса
HTTP-код Описание
200 OK Сервер успешно обработал запрос, и клиент может получить запрашиваемый документ в теле ответа
201 Created Locatuion Сервер успешно создал новый URL, заданный в HTTP-заголовке Locatuion
202 Accepted Запрос принят сервером для обработки, но она еще не завершена
203 Non-Authoritative Information Метаинформация в заголовке запроса не связана с данным сервером и скопирована с другого сервера
204 No Content Выполнение запроса завершено, но никакой информации отправлять обратно не требуется. Клиент может продолжать просматривать текущий документ
205 Reset Content Клиент должен сбросить текущий документ. Этот HTTP-заголовок можно использовать для сброса и удаления всех значений полей ввода в HTML-форме
206 Prtial Content Сервер выполнил неполный запрос ресурса методом GET. Этот HTTP-код используется для ответа на запросы, содержащие HTTP-заголовок Range. Сервер отправляет HTTP-заголовок Content-Range, чтобы указать, какой сегмент данных приложен
300 Multiple Choices Запрашиваемый ресурс соответствует набору документов. Сервер может отправить информацию о каждом документе с его собственным местоположением и информацией по согласованию содержимого, оставляя выбор на усмотрение клиента
301 Moved Permanently Запрашиваемый ресурс на сервере отсутствует. Для переадресации клиента на новый URL отправляется HTTP-заголовок Locatuion. Все последующие запросы должны отправляться на новый URL
302 Moved Temporarily Запрашиваемый ресурс временно перемещен. Для переадресации клиента на новый URL отправляется HTTP-заголовок Locatuion. В последующих запросах клиент может продолжать использовать старый URL
303 See Other Запрашиваемый ресурс найден в другом месте, его местоположение уточняется сервером при помощи HTTP-заголовка Locatuion
304 Not Modified Сервер использует этот HTTP-код в соответствии с HTTP-заголовком if-Modified-Since. Это означает, что запрашиваеьый документ не модефицировался с даты, определенной в HTTP-заголовке if-Modified-Since
305 Use Proxy Для получения запрашиваемого ресурса клиент должен использовать прокси-сервер, адрес которого определяется сервером в HTTP-заголовке Locatuion
307 Temporary Redirect Запрашиваемый ресурс временно перемещен в другое место. Для переадресации клиента на новый URL отправляется HTTP-заголовке Locatuion
Таблица. HTTP-коды ошибочного запроса
HTTP-код Описание
400 Bad Request В запросе клиента обнаружена синтаксическая ошибка
401 Unauthorized Запрос требует аутентификации клиента. Для уточнения типа аутентификации и области запрашиваемого ресурса сервер отправляет HTTP-заголовок WWW-Authentificate
402 Payment Required Данный HTTP-код зарезервирован для будущего использования в электронной коммерции
403 Forbidden Доступ к запрашиваемому ресурсу запрещен. Клиент не должен повторять запрос.
404 Not Found Запрашиваемый документ отсутствует на сервере
405 Method Not Allowed Метод запроса, используемый клиентом, неприемлем. Сервер отправляет HTTP-заголовок Allow, в котором уточняются допустимые методы для получения доступа к запрашиваемому ресурсу
406 Not Acceptable Запрашиваемый ресурс недоступен в том формате, который может принимать клиент (клиент обычно уточняет эти форматы в специальном HTTP-заголовке Accept). Если запрос не является запросом HEAD на получение лишь HTTP-заголовков с сервера без тела документа, то сервер может отправить заголовки Content-Language, Content-Encoding, Content-Type, чтобы определить, какие форматы являются доступными
407 Proxy Authentification Required Несанкционированный запрос доступа к прокси-серверу: клиент должен аутентифицировать себя на прокси-сервере. Сервер отправляет HTTP-заголовок Proxy Authentificatе со схемой аутентификации и областью запрашиваемого ресурса
408 Request Time-Out Клиент не завершил свой запрос за время ожидания запроса, заданное серверу,однако можетповторить запрос
409 Conflict Возник конфликт запроса клиента с другим запросом. Вместе скодом состояния сервер может переслать информацию о типе конфликта
410 Gone Запрашиваемый ресурс удаленен с сервера
411 Length Required Клиент должен прислать в запросе HTTP-заголовок Content-Length
412 Precondition Filed Если запрос клиента содежит один или более HTTP-заголовков if ..., сервер использует этот HTTP-код для оповещения, что одно или более условий, заданных в этих заголовках, не выполняются
413 Request Entity Too Large Сервер отказывается выполнять запрос: слишком длинное тело сообщений
414 Request-URI Too Long Сервер отказывается выполнять запрос: слишком длинный URI(URL)
415 Unsupported Media Type Сервер отказывается выполнять запрос: отсутствует поддержка формата тела сообщения
417 Expectation Failed Сервер не смог выполнить требования HTTP-заголовка Expect Request
Таблица. HTTP-коды ошибочного запроса
HTTP-код Описание
500 Internal Server Error Ошибка конфигурации сервера или внешней программы
501 Not Implemented Сервер не поддерживает функции, требуемые для выполнения запроса
502 Bad Gateway Неверный ответ вышестоящего сервера или прокси сервера
503 Servise Unavailable Служба временно недоступна. С целью оповещения о времени открытия доступа к службе сервер может отправить заголовок Retry-After
504 Gateway Time-Out Шлюз или прокси-сервер временно заблокирован
505 HTTP Version Not Supported Не поддерживается используемая клиентом версия протокола HTTP

При работе HTTP-заголовками следует помнить, что они всегда предваряют содержимое страницы. Вывод любой информации (при помощи конструкции echo, функции print() или непосредственно вне тегов <?phpи?>) в окно браузера приводит к тому, что начинается отправка HTTP-документа. Согласно протоколу, HTTP-заголовки отправляются перед телом документа, и последующие попытки отправить дополнительные заголовки заканчиваются неудачей.

Перевод строки перед функцией header() блокирует ее работу
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<?php
header("Location: http://sevidi.narod.ru");
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Перевод строки перед функцией header() блокирует ее работу</title>
</head>

<body>
</body>
</html>

В результате переадресация не осуществляется, а функция header() выводит предупреждение Warning: Cannot modify header information - headers already sent by (output started at D:\sevidi\373.php:2) in D:\sevidi\373.php on line 3, сообщающее, что отправка HTTP-заголовка невозможна, поскольку уже начата передача тела HTTP-документа. Иногда пробелы и переводы строк могут быть расположены внутри файлов, включаемых при помощи конструкций include() и require().

В ряде случаев нельзя быть заранее уверенным, отправлены HTTP-заголовки или все еще имеется возможность использовать функцию header(). Чтобы выяснить это, можно воспользоваться функцией headers_sent(), которая имеет следующий синтаксис:

dool headers_sent(&$file [, &$line])

Функция возвращает false, если HTTP-заголовки не были отправлены клиенту, и true — в противном случае. После отправки HTTP-заголовков функция при помощи необязательных аргументов $file и $line может сообщить, в каком файле и строке была начата передача тела HTTP-документа.

Использование функции headers_sent()
<?php
echo "Hello<br>";
if(!headers_sent($filename, $linenum))
{
header("Location: http://sevidi.narod.ru");
exit;
}
else
{
echo "Передача HTTP-документа начата в файле $filename в строке $linenum. Поэтому перенаправление на другой ресурс невозможно.";
exit;
}
?>

Иногда бывает полезно проконтролировать, какие HTTP-заголовки были отправлены клиенту. Для этого удобно воспользоваться функцией headers_list(), которая имеет следующий синтаксис:

array headers_list()

Функция возвращает массив, содержащий отправленные клиенту HTTP-заголовки. Рассмотрим пример работы функции headers_list(); получаемый в результате ее работы массив для удобства восприятия выводится при помощи функции print_r() в тегах <pre> и </pre>, сохраняющих отступы и переводы строк.

Примечание. Клиенту отправляется произвольный HTTP-заголовок X-my-header со значение "Hello world". Нестандартные HTTP-заголовки, как правило, всегда предваряются префиксом Х-.

Использование функции headers_list()
<?php
header("X-my-header: Hello world!");
$arr=headers_list();
echo "<pre>";
print_r($arr);
echo "</pre>";
?>

Скрипт выведет следующий дамп массива HTTP-заголовков:

Array
(
[0] => X-Powered-By: PHP/5.2.8
[1] => X-my-header: Hello world!
)

Это не полный список HTTP-заголовков, которые получает клиент: это лишь те заголовки, которые отправляет РНР-скрипт. Помимо них клиент получает HTTP-заголовки, отправленные веб-сервером. Получить полный список HTTP-заголовков к странице можно при помощи сокетов.