Протокол HTTP и работа с заголовками
Протокол HTTP
Как работает WWW (всемирная паутина, веб) в двух словах:
Иными словами, весь современный веб построен на модели клиент-серверного взаимодействия. И чтобы весь этот процесс оказался возможным, необходим универсальный язык-протокол, который будет понимать и сервер, и браузер. Такой протокол есть, а называется он HTTP.
Как работает HTTP, и зачем нам это знать
Программировать на PHP можно и без знания протокола HTTP, но есть ряд ситуаций, когда для решения задач нужно знать, как именно работает веб-сервер. Ведь PHP — это, в первую очередь, серверный язык программирования.
Протокол HTTP очень прост и состоит, по сути, из двух частей:
Сначала идёт список заголовков, затем пустая строка, а затем (если есть) тело запроса/ответа.
И клиент, и сервер могут посылать друг другу заголовки и тело ответа, но в случае с клиентом доступные заголовки будут одни, а с сервером — другие. Рассмотрим пошагово, как будет выглядеть работа по протоколу HTTP в случае, когда пользователь хочет загрузить главную страницу социальной сети «Вконтакте».
1. Браузер пользователя устанавливает соединение с сервером vk.com и отправляет следующий запрос:
2. Сервер принимает запрос и отправляет ответ:
3. Браузер принимает ответ и показывает готовую страницу
Больше всего нам интересен самый первый шаг, где браузер инициирует запрос к серверу vk.com
Рассмотрим подробнее, что там происходит. Первая строка запроса определяет несколько важных параметров, а именно:
GET — это метод (глагол), который мы применяем для доступа к указанной странице.
GET является самым часто используемым методом, потому что он говорит серверу о том, что клиент всего лишь хочет прочитать указанный документ. Но помимо GET есть и другие методы, один из них мы рассмотрим уже в следующем разделе.
Больше всего здесь интересен именно код состояния, он же код ответа сервера.
В этом примере код ответа — 200, что означает: сервер работает, документ найден и будет передан клиенту. Но не всегда всё идет гладко.
Например, запрошенный документ может отсутствовать или сервер будет перегружен, в таком случае клиент не получит контент, а код ответа будет отличным от 200.
Спецификация HTTP 1.1 определяет 40 различных кодов HTTP.
После стартовой строки следуют заголовки, а затем тело ответа.
Работа с заголовками в PHP
В PHP есть все возможности для взаимодействия с протоколом HTTP:
Разберём всё по порядку.
Получение тела запроса
Получение заголовков запроса
Пример, как получить предыдущую страницу, с которой перешёл пользователь:
Добавление/изменение заголовков ответа
В PHP-сценарии можно управлять всеми заголовками ответа, которые попадут к пользователю вместе с контентом страницы. Это возможно, потому что PHP работает на стороне веб-сервера и имеет с ним очень тесную интеграцию.
Вот примеры сценариев, когда пригодится управление заголовками ответа:
Управление телом ответа
Параметры запроса
На сайте дневника наблюдений за погодой мы сделали отдельную страницу, чтобы показывать на ней информацию о погоде из истории за один конкретный день. То есть страница одна, но показывает разные данные, в зависимости от выбранного дня.
Также пользователи хотят добавить в закладки адреса страниц с нужными им днями. Получается, что имея только один сценарий сделать страницу, способную показывать дневник погоды за любой день невозможно? Вовсе нет!
Из чего состоит URI
URI — это уникальный идентификатор ресурса. Ресурс в нашем случае — это полный путь до страницы сайта. И вот как может выглядеть ресурс для показа погоды за конкретный день:
http://weather-diary.ru/day.php?date=2017-10-15
В примере выше указывается два аргумента: дата и единица измерения температуры.
Параметры запроса как внешние переменные
Теперь в адресе страницы используются параметры запроса, но какая нам от этого польза? Она состоит в том, что если имя страницы вызывает к исполнению соответствующий PHP-сценарий, то параметры запроса превращаются в специальные внешние переменные в этом сценарии. То есть, если в адресе присутствуют такие параметры, то их легко получить внутри кода сценария и выполнить с ними какие-нибудь действия. Например, показать погоду за конкретный день в выбранных единицах измерения.
Получение параметров запроса
Формирование URI с параметрами запроса
Иногда нужно совершить обратную операцию: сформировать адрес страницы, включив туда нужные параметры запроса из массива.
Скажем, на странице погодного дневника надо поставить ссылку на следующий и предыдущий день. Нужно также сохранить выбранную единицу измерений. То есть необходимо сохранить текущие параметры запроса, поменять значение одного из них (день), и сформировать новую ссылку.
Вот как это можно сделать:
Здесь мы использовали две функции:
header
Описание
int header (string string [, bool replace])
header() используется для отправки необработанных HTTP-шапок. См. в спецификации HTTP/1.1 информацию о HTTP headers.
Необязательный параметр replace указывает, должна ли шапка замещать предыдущую аналогичную шапку, или нужно добавить вторую header того же самого типа. По умолчанию выполняется замещение, но, если вы передаёте FALSE в качестве второго аргумента, вы можете форсировать создание нескольких headers одного типа. Например:
Здесь два особых вызова шапок. В первом это header, начинающийся строкой «HTTP/» (регистр не имеет значения), используемый для создания HTTP статус-кода для отправки. Например, если вы сконфигурировали Apache для использования PHP-скрипта для обработки запросов отсутствующих файлов (используя директиву ErrorDocument), вам потребуется удостовериться, что ваш скрипт генерирует соответствующий статус-код.
Примечание: строка шапки HTTP-статуса всегда будет отправляться первой клиенту, независимо от того, идёт вызов header() первым или нет. Этот статус может быть переопределён вызовом header() с новой строкой статуса в любое время, если только HTTP headers уже не отправлены.
Примечание: в PHP 3 это работает только в том случае. если PHP скомпилирован как Apache-модуль. Вы может добиться того же эффекта, используя шапку Status.
Второй особый случай это «Location:» header. Здесь header не только отсылается обратно браузеру, но также возвращается статус-код REDIRECT (302), если только какой-нибудь 3xx статус-код не был уже установлен.
Примечание: HTTP/1.1 требует абсолютного URI в качестве аргумента для Location: включая схему, имя хоста и абсолютный путь, но некоторые клиенты принимают относительные URI. Как правило вы можете сами использовать $_SERVER['HTTP_HOST'], $_SERVER['PHP_SELF'] и dirname() для создания абсолютного URI из относительного:
PHP-скрипты часто генерируют динамическое содержимое, которое обязано не кэшироваться клиентским браузером или proxy-кэшами между клиентским браузером и сервером. Во многих прокси и клиентах можно отключать кэширование
Примечание: вы можете обнаружить, что ваши страницы не кэшируются, даже если вы не выводите все выше указанные шапки. Есть опции, которые могут быть установлены пользователями в своих браузерах, изменяющие поведение по умолчанию кэширования. Отправляя вышеуказанные шапки, вы должны переопределить любые установки, которые иначе могут кэшировать ваши скрипты.
Кроме того, session_cache_limiter() и установка конфигурации session.cache_limiter могут использоваться для автоматической генерации корректны шапок кэширования, когда используются сессии.
Помните, что header() обязана вызываться до отправки любого вывода: нормальными ли тэгами HTML, пустыми строками в файле или из PHP. Очень частой ошибкой является чтение кода функциями include() или require(), или другой функцией доступа к файлу, и наличие пробелов или пустых строк, которые выводятся до вызова header(). Та же проблема возникает при использовании едингого PHP/HTML-файла.
Примечание: в PHP 4 вы можете использовать буферизацию вывода для решения этой проблемы, передавая браузеру весь ваш вывод, буферизуемый на сервере до отправки. Вы можете сделать это вызовом ob_start() и ob_end_flush() в вашем скрипте, или установив директиву конфигурации output_buffering в файле php.ini или файлах конфигурации сервера.
Если вы хотите, чтобы пользователю задавался вопрос о сохранении данных, высылаемых вами, таких как сгенерированный PDF-файл, вы можете использовать шапку Content-Disposition для предоставления рекомендуемого файла и форсировать отображение браузером диалога save.
Примечание: в Microsoft Internet Explorer 4.01 имеется жучок, не дающий реализовать это. Средства от этого нет. Также имеется жучок в Microsoft Internet Explorer 5.5, но его можно исправить, обновив до Service Pack 2 или новее.
Примечание: если safe mode включён, uid скрипта добавляется к части realm шапки WWW-Authenticate, если вы устанавливаете эту шапку (используется для HTTP Authentication).
Header php что такое
Заголовки HTTP используются для «общения» браузера и web-сервера, например, когда браузер запрашивает какой-либо документ, он посылает заголовок GET, а когда сервер возвращает тип документа, то он делает это ни как-нибудь, а в заголовке Content-type.
Мы уже частично рассматривали заголовки протокола HTTP, но теперь остановимся на них подробнее.
Итак, приведем список и краткое описание основных заголовков HTTP.
Заголовок Accept
Заголовок Accept предназначен для информирования сервера о типах данных, которые поддерживаются клиентом (браузером). В этом заголовке браузер перечисляет, какие типы документов он «понимает». Пере-
числение идет через запятую.
Используется переменная окружения HTTP_ACCEPT. Пример использования:
Accept: text/html, text/plain, image/jpeg
В последнее время вместо списка указывается значение *.*, что означает «все типы».
Заголовок Content-type
Данный заголовок предназначен для идентификации типа передаваемых данных. При этом заголовок Content-type использует переменную окружения CONTENT_TYPE. Обычно для этого заголовка указывается значение application/x-www-form-urlencoded. Таким образом, указывается формат, в котором все управляющие символы (т.е. символы, не являющиеся алфавитно-цифровыми) специально кодируются. О некоторых других MIME-типах вы можете узнать здесь.
Это тот самый формат передачи, который используется методами GET и POST.
Довольно распространен и другой формат, multipart/form-data.
Сервер никак не интерпретирует рассматриваемый заголовок, а просто передает его сценарию через переменную окружения.
Пример: Content-type: text/plain
Заголовок Content-length
Этот заголовок содержит строку, в которой записана длина передаваемых данных в байтах при использовании метода передачи POST. За заголовком закреплена одноименная переменная CONTENT_LENGTH.
Если задействуется метод GET, то этот заголовок отсутствует, и значит, переменная окружения не устанавливается.
Заголовок Cookie
В этом заголовке хранятся все Cookies. Данный заголовок использует переменную окружения HTTP_COOKIE. Для установки Cookies используется заголовок Set-Cookie.
Заголовок GET
Об этом заголовке мы упоминали ранее.
Заголовок GET использует следующие переменные окружения:
Заголовок Location
Получив заголовок Location вместе с указанным в нем URL, сервер немедленно переходит по указанному URL, не дожидаясь, пока тело документа загрузится:
Пример: Location: http://www.somehost.com/
Заголовок POST
Этот заголовок использует те же переменные окружения, что и заголовок GET (переменная REQUEST_METHOD содержит значение POST). Напомним, что данные методом POST можно передавать в конце заголовков.
Напомним формат заголовка POST: POST сценарий?параметры HTTP/1.0
Заголовок Pragma
Пример заголовка: Pragma: no-cache
Данный заголовок содержит название и версию программного обеспечения сервера. Например:
Server: Apache/1.3.23 (Unix) (Red-Hat/Linux) mod_ssl/2.8.7 OpenSSL/0.9.6b Dav/1.0.3 PHP/4.3.0 mod_perl/1.26 configured
Заголовок Referer
С помощью этого заголовка можно узнать ссылающийся на нас сервер. Это бывает полезно, когда нам необходимо узать обратные ссылки, например, при анализе эффективности сетевой рекламы.
Переменная окружения: HTTP_REFERER.
Заголовок User-Agent
Содержит версию браузера. Например: User-Agent: Mozilla/5.0 (compatible; Konqueror/3.0.0-10; Linux).
Переменная окружения: HTTP_REFERER.
Некоторые комментарии по HTTP-заголовкам
Мы ознакомились с названиями заголовков и соответствующим им переменным окружения.
Необходимо помнить основные приципы:
Передача заголовков HTTP в PHP
В PHP есть встроенные функции для работы с заголовками HTTP.
Для передачи заголовков HTTP предназначена функция header()
Приведем практические примеры:
( «Location: http://www.example.com/» ); /* Производит перенаправление браузера на другой ресурс */
/* Внимание! Убедитесь, что код, расположенный ниже не исполняется */
exit;
?>
// Date in the past
header ( «Expires: Mon, 26 Jul 1997 05:00:00 GMT» );
// HTTP/1.0
header ( «Pragma: no-cache» );
?>
Функция header в php
$string:
сам заголовок. Бывает двух типов. Первый начинается с «HTTP/» (header(«HTTP/1.0 404 Not Found»);). Второй начинается не с «HTTP/». Состоит из двух частей «имя парметра: значение» (например, «Location: http://www.example.com/» или «Content-type: application/pdf»).
Второй параметр булевого типа. Если true (по умолчанию), то заголовок замещает предыдущий с таким же именем параметра, если false, то передаётся несколько параметров одного типа:
Третий параметр, $http_response_code, можно использовать для передачи HTTP-заголовков ответа (200, 404 и т.п.):
Функция header используется для простановки заголовков «вручную», для кеширования, для внешнего перенаправления, для выставления правильного mime-типа и кодировки.
Пример простановки заголовков «вручную»:
Пример внешнего перенаправления:
Пример реализации скачивания файлов по расширению (полезен перечислением mime-типов):
Заголовок header(«Content-Transfer-Encoding: binary»); очень важен для того, чтобы заставить браузер скачивать файл, а не отображать текстовое содержимое.
Пример установки использумой кодировки:
Самая интересная часть: кеширование (w3.org).
Для начала надо заметить, что HTTP/1.0 моежт не поддерживать основную директиву (Cache-Control), поэтому в этом случае нужно использовать заголовок Pragma: no-cache. Хотя уже давно все поддерживают 1.1, поэтому особого смысла это делать нет.
Заголовок Cache-Control может использоваться как для запроса, так и для ответа. Нас интересует только ответ.
Синтаксис следующий:
«Cache-Control: значение».
Значения:
Заголовок Expires используется для задания даты, при которой кеш считается просроченным
(Expires: Thu, 01 Dec 1994 16:00:00 GMT), можно задавать дату в прошлом (значит, кеш уже просрочен) или в будущем. При этом если используется заголовок Cache-Control: max-age=значение, то он переопределяет заголовок Expires.
Заголовок ETag используется для создания «тегов», по сравнению которых можно определить, актуален ли кеш в браузере/на прокси-сервере.
Использование:
ETag: уникальный тег.
Обычно для создания тегов советуют использовать что-то вроде:
Файл темы header.php — тонкости настройки
В этом руководстве мы поговорим о header.php, обязательном файле для каждой WordPress темы. Я покажу вам хороший пример этого файла и дам советы по поводу, что в нем должно быть, а чего быть не должно.
Вы также можете ознакомиться с этой информацией, посмотрев наш видео урок:
Шаг 1. Введение
В этом файле у нас не только логотип и меню, есть еще также тег head и много других тегов, например: link, script, meta и title.
Я написал пример файла header.php. Я постарался создать максимально полный файл, но не стесняйтесь комментировать это руководство с советами по поводу содержимого.
Помните, что ваша «шапка» – это контент, который отображается на всех страницах вашего сайта. Например, логотип и меню показываются на всех страницах, так что они будут добавлены в header.php.
Если элемент отображается только на конкретной странице, вам нужно еще раз подумать, нужно ли добавлять этот элемент в файл вашей шапки.
Давайте же приступим к работе, я надеюсь, вам понравится!
Шаг 2. Готовый Код
Здесь вы можете получить полный код для использования в вашей теме. Прочтите другие шаги для того, чтобы понять, что конкретно делает каждая строка.
Для начала, вставьте эти строки в верх вашего файла functions.php: (помните, что вам нужно будет отредактировать пути к вашим файлам CSS и JavaScript)
Теперь в файл header.php добавьте эти строки: (помните, что вам нужно будет отредактировать пути к вашим файлам CSS и JavaScript)
В шапке «должны» быть некоторые вещи. Этот шаблон, который я сделал, делает следующее: (в следующих шагах я поговорю о каждом конкретном)
Дальше мы будем говорить о коде, который мы использовали. Вы узнаете о том, зачем нужно его использовать.
Шаг 3. Файл functions.php
Давайте поговорим о файле functions.php, мы добавили следующие строки в файл:
Первая строка создает константу THEME_DIR, которая хранит директорию шаблона. Мы создаем эту константу для того, чтобы оптимизировать тему. Если вы посмотрите в наш файл header.php, вы увидите, что нам нужно использовать директорию несколько раз, мы используем ее также в файле functions.php, чтобы вывести путь к теме. Если мы постоянно вызываем get_template_directory_uri(), мы просто создаем запросы. Создавая константу и используя ее, мы экономим ресурсы процессора, поскольку мы вызываем функцию только один раз.
Эта строка удаляет тег Meta Generator, поскольку этот тег показывает всем установленную версию WordPress. Эта информация может позволить злоумышленнику узнать баги вашей версии и использовать их.
Добавление вашего CSS
Сначала мы создаем функцию под названием enqueue_styles и затем мы вызываем функцию add_action. Эта строка говорит WordPress, что он должен вызвать нашу функцию, когда происходит событие ‘wp_enqueue_scripts’, что происходит при нашем вызове wp_head() в header.php!
Внутри нашей функции у нас следующие строки:
Сначала мы зарегистрируем нашу таблицу стилей и добавим ее в очередь WordPress.
Мы используем функцию wp_register_style, чтобы зарегистрировать стиль. Эта функция требует следующее:
Затем мы вызываем функцию wp_enqueue_style и передаем в качестве параметра имя нашего стиля, который будет добавлен.
Чтобы добавить в файл больше стилей, просто скопируйте эти две строки и измените имя, директорию и другие параметры.
Добавление скриптов
Теперь мы рассмотрим функцию, которая добавляет наши скрипты.
Здесь процесс тот же, разница в том, что мы используем другие функции для добавления скриптов.
Чтобы добавить скрипты, мы используем функции wp_register_script и wp_enqueue_script. Функция wp_register_script требует следующих параметров:
Затем мы вызываем функцию wp_enqueue_script и передаем в качестве параметра имя нашего скрипта, который мы хотим добавить.
Чтобы добавить больше скриптов в ваш файл, просто скопируйте эти две строки и измените имена, директорию и другие параметры.
Шаг 4. header.php
Сначала я перечислю здесь ссылки на библиотеки, которые мы можем использовать в этом шаблоне, я уже использую jQuery и HTML5 Shim в этом шаблоне, но вы можете добавить другие.
Вы можете скачать эти библиотеки и изменить пути в вашем файле header.php.
Doctype
В этом шаблоне мы используем стандартный доктайп HTML5:
Это действительно удобно потому, что вы можете создать правило внутри CSS файла, чтобы оно подействовало на объект, если браузер IE 7:
Но вы также можете создать отдельный файл CSS и привязать его внутри области условий, мы будем говорить об этом на следующих шагах. Выбор за вами.
Мета-теги очень важны, т.к. они передают некоторую информацию браузеру, чтобы быть уверенными в том, что ваша тема будет правильно воспринята.
Эта строка подтверждает, что браузер не будет использовать Quirks Mode, это очень полезно, так как этот режим может поломать разметку.
Эта строка сообщает браузеру кодировку, чтобы избежать неизвестных символов.
Просто основные мета теги, которые могут улучшить SEO вашей темы. Вы можете добавить ключевые слова, которые описывают сайт и написать название вашего бизнеса.
Этот тег удаляет/сбрасывает любое увеличение мобильным устройством, по типу iPad и iPhone, очень удобно, если вы работаете с гибкой разметкой.
Эта строка добавляет фавиконку для вашей страницы, добавляет немного профессионального вида вашему сайту.
Ссылка на RSS ленту вашего сайта.
Ссылка на пингбек URL вашего сайта.
Тег заголовка очень важен, поскольку он заменяет заголовок по умолчанию и улучшает ваши позиции в поисковых системах.
wp_head()
Это очень важная функция, вы обязательно должны вызвать эту функцию! С помощью этой функции WordPress добавляет код из плагинов, JavaScript библиотек и т.д.





