В избранное    Домой   

Вторник,  10 Dec 2024 г., 08:44
Лучше кусок сухого хлеба, и с ним мир, нежели дом, полный заколотого скота, с раздором. /Притчи/

 Логин:  

 Пароль: 




Анонсы:
=== Дата: 25/08/2011     Автор: Крис Ньюман ===

PHP. Урок 16 Взаимодействие с Web-сервером

Урок 16. Взаимодействие с Web-сервером

В этом уроке рассматриваются способы взаимодействия PHP с Web-сервером.

HTTP-заголовки

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

Вот пример HTTP-заголовков Web-сервера с поддержкой PHP, которые приходят в ответ на запрос браузера вместе с обычной Web-страницей:

HTTP/1.1 200 OK
Date: Tue, 14 Dec 2004 21:17:28 GMT
Server: Apache/1.3.29 (Unix) mod_gzip/1.3.26.1a PHP/4.3.9 mod_ssl/2.8.16 OpenSSL/0.9.7c
X-Powered-By: PHP/4.3.9
Connection: close
Content-Type: text/html; charset=iso-8859-1

Отправка специальных заголовков

С помощью функции header можно отправлять различные HTTP-заголовки. Сначала отправим заголовок, который не выполняет никаких действий. Все заголовки, начинающиеся с X, игнорируются браузером и содержат дополнительную информацию. Например, заголовок X-Powered-By показывает, что на сервере установлен PHP. Следующий HTTP-заголовок выводит имя автора:

header(“X-PHP-Author: Chris Newman <chris@lightwood.net>”);

Конечно,это не приносит никакой пользы, кроме того, что тешит тщеславие автора. Обычный пользовательский браузер даже не заметит этого заголовка!

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

setcookie(“mycookie”, “somevalue”);
header(“Set-Cookie: mycookie=somevalue”);

Заголовки перенаправления

На практике чаще всего используется заголовок Location. Он дает браузеру указание перейти на другой URL. Этот заголовок позволяет управлять порядком прохождения по страницам в зависимости от событий в сценарии. Следующая инструкция перенаправляет пользовательский браузер на другую страницу:

header(“Location: anotherpage.php”);

В заголовке Location можно использовать относительные и абсолютные URL. Это позволяет перенаправить пользователя даже на другой домен, как в примере ниже:

header(“Location: http://www.имя_домена.com/newpage.php”);

После отправки заголовка Location нужно сразу прервать выполнение сценария командой exit. Тогда браузеру не отправится другая информация.

Проверка факта отправки заголовков

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

Если заголовки уже отправлены, то при повторить это еще раз, PHP выдаст ошибку:

Warning: Cannot modify header information – headers already send by (output started at /home/chris/public_html/header.php:4) in /home/chris/public_html/header.php on line 5

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

В PHP есть специальная функция headers_sent, которая позволяет проверить, отправлены ли заголовки HTTP. Функция возвращает TRUE, если заголовки отправлены. А FALSE получим, если еще можно отправить дополнительные заголовки.

Условие ниже проверяет, можно ли отправить дополнительные заголовки, и только после этого посылает заголовок перенаправления:

if (!headers_sent()) {
    header(“Location: newpage.php”);
}

Конечно, в случае неудачи нужно, чтобы сценарий продолжил работу.

Два необязательных параметра функции headers_sent позволяют узнать название сценария и номер строки, в которой произошла отправка заголовков. Это полезно, если заголовки отправлены по ошибке и нужно узнать, где это произошло.

Сценарий в листинге 16.1 пытается отправить заголовок Location. В случае неудачи предлагается альтернативный путь попадания на нужную страницу. Можно выполнить его на собственном сервере. Для этого в сценарии перед первым дескриптором <?php нужно поставить пробел. Это вызовет преждевременную отправку заголовков.

Листинг 16.1. Сценарий с проверкой возможности отправки заголовков


<?php
$destination = “http://www.lightwood.net/”;
if (!headers_sent($filename, $line)) {
    header(“Location: $location”);
}
else {
    echo “Заголовки уже отправлены в строке $line файла $filename <br>”;
    echo “<A HREF=\”$destination\”>Нажмите чтобы продолжить</A>”;
}
?>

Вывод HTTP-заголовков

Функция headers_list позволяет узнать список заголовков, которые уже отправлены или будут отправлены. Эта функция доступна в PHP 5 и выше. Она возвращает массив с заголовками.

Чтобы обработать этот массив, можно воспользоваться циклом. Но обычно нужно просто посмотреть список заголовков. Для этого идеально подойдет функция print_r:

print_r(headers_list());

Этот код нужно окружить дескрипторами <PRE>, чтобы получить результат в удобочитаемом виде:

Array
(
    [0] => X-Powered-By: PHP/5.0.2
    [1] => Set-Cookie: mycookie=somevalue
    [2] => Content-type: text/html
)

Изменение настроек кэширования

С помощью HTTP-заголовков можно изменить режим кэширования для конкретной Web-страницы. Этот механизм управляет местом, откуда будет загружаться страница при повторном доступе. Страница может полностью обновляться или загружаться с кэша пользовательского браузера или Internet-провайдера. Таким образом уменьшается нагрузка на Internet-канал.

Заголовок Cache-Control задает механизм кэширования для страницы. Основные управляющие значения этого заголовка приведены в табл. 16.1.

Зачастую кэширование убирается для того, чтобы страница обновлялась при повторном посещении.

Таблица 16.1. Основные установки для настройки кэширования

Значение Описание
public Можно сохранять в любом кэше.
private Можно сохранять в кэше браузера, но не в общих системах кэширования.
no-cache Нельзя кешировать в любом виде между Web-сервером и браузером.

Обычно системы кэширования сами распознают, где происходит частое изменение содержимого. Например, для динамических страниц с использованием PHP. Но для полной уверенности в обновлении содержимого, можно использовать этот вспомогательный механизм.

Для того, чтобы избежать кэширования в любом виде, используются следующие заголовки, которые запрещают все виды кэширования:

header(“Cache-Control: no-store, no-cache, must-revalidate”);
header(“Cache-Control: post-check=0, pre-check=0, false”);
header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”);
header(“Last-Modified: ”. date(“D, d M Y H:i:s”) . “ GMT”);

Здесь используется несколько различных типов заголовков.

Заголовок Expires указывает браузеру на дату актуальности документа. В данном случае документ всегда будет устаревшим и нуждается в обновлении при очередном посещении.

Заголовок Last-Modified указывает на дату последнего изменения документа. Если использовать функцию date, в заголовке будет передаваться текущая дата. Поэтому браузер будет считать, что страница только что изменилась, и запросит новую копию документа.

Контроль кэширования в сеансах. При открытии сеанса PHP вместе с другими заголовками автоматически отправляется заголовок no-cache. Можно изменить механизм кэширования с помощью функции session_cache_limiter, используя для аргумента одно из значений, приведенных в табл. 16.1.

Переменные окружения сервера

Рассмотрим, какую информацию может получить PHP от Web-сервера.

Суперглобальный массив $_SESSION содержит элементы, в которых храниться информация об окружении Web-сервера во время текущего запроса. Чтобы увидеть полный список в рамках сценария, нужно выполнить следующую инструкцию:

print_r($_SERVER);

Примеры в этом разделе подходят для большинства Web-серверов. Но некоторые могут не поддерживать все приведенные значения или использовать другие имена. Чтобы узнать доступные значения, достаточно выполнить выражение выше.

Информация о сценарии

Имя сценария содержится в элементе $_SERVER["SCRIPT_NAME"]. Эта переменная позволяет создавать формы, которые отправляют содержимое самому себе. Тогда при смене имени файла не нужно менять параметр ACTION в сценарии. Ниже приводится пример:

<FORM ACTION=”<?php print $_SERVER[“SCRIPT_NAME”];?>” METHOD=POST>

Элемент REQUEST_URI похож на SCRIPT_NAME, но содержит полный URI запрашиваемой страницы. Он состоит из полного пути к сценарию включая знак вопроса и значения строки запроса, если они есть. Строка запроса не включается в элемент SCRIPT_NAME. В чистом виде она содержится в элементе $_SERVER[“QUERY_STRINNG”].

Узнать имя домена, на котором выполняется сценарий,можно в переменной $_SERVER[“HTTP_HOST”]. Web-сервер может работать с несколькими именами доменов; это позволяет определить, какому из них посылается запрос.

Информация о пользователе

В элементе HTTP_USER_AGENT содержится информация о версии браузера и операционной системе пользователя. Она может выглядеть примерно так:

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0
Lynx/2.8.5dev.7 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.7a

Три примера выше соответствуют браузерам Internet Explorer, Mozilla Firefox и Lynx. Отметим, что Internet Explorer и Mozilla Firefox идентифицируют себя как Mozilla-браузеры. Поэтому, чтобы точно определить, какой из них используется, нужно проанализировать информацию дальше.

Условие ниже позволяет генерировать различный вывод для Internet Explorer и Firefox:

if (strstr($_SERVER[“HTTP_USER_AGENT”], “MSIE”)) {
    echo “Вы используете Internet Explorer”;
}
elseif (strstr($_SERVER[“HTTP_USER_AGENT”], “Firefox”)) {
    echo “Вы используете Firefox”;
}
else {
    echo “Вы пользуетесь другим браузером ”;
}

Такой механизм может понадобится из=за различных реализаций DHTML и JavaScript в этих браузерах.

В элементе REMOTE_ADDR содержится IP-адрес, с которого происходит обращение к странице. Это может быть адрес пользователя или прокси-сервера Internet-провайдера. Иногда этот параметр используется для реализации безопасной системы аутентификации.

Если в REMOTE_ADDR находится значение прокси-сервера, то в элементе HTTP_X_FORVARDED_FOR находится IP-адрес пользовательского компьютера.

Имя пользователя, который авторизовался через базовую HTTP-аутентификацию, находится в элементе $_SESSION[“REMOTE_USER”].

Информация о сервере

Другие элементы $_SERVER позволяют получить различную информацию о настройках Web-сервера.

Например, $_SERVER[“SERVER_NAME”] соответствует директиве Apache ServerName. Это главное имя данного Web-сервера. Оно может не совпадать с именем домена, куда выполняется запрос, и даже со значением $_SERVER[“HTTP_HOST”]. Аналогично, в $_SESSION[“SERVER_ADMIN”] содержится адрес электронной почты Web-мастера, установленный с помощью инструкции ServerAdmin.

Элементы SERVER_ADDR и SERVER_PORT содержат IP-адрес и номер порта на котором работает Web-сервер. Элемент $_SEVER[“REQUEST_METHOD”] содержит информацию о методе (GET или POST) передачи информации в сценарий.

И напоследок: в переменной $_SERVER[“SERVER_SOFTWARE”] хранится информация о программном обеспечении, которое используется на Web-сервере. Оно совпадает с тем, что отправляется в заголовке Server, который рассматривался в начале урока. Выглядит это примерно так:

Apache/1.3.29 (Unix) mod_gzip/1.3.26.1a PHP/4.3.9 mod_ssl/2.8.16 OpenSSL/0.9.7c

Резюме

В этом уроке вы узнали, как организовать взаимодействие с Web-сервером. В следующем уроке вы узнаете, как работать с файловой системой при помощи PHP.


<<назад

Погода в Рудне
(Волгоградcкая обл.)

Подробнее >>


Курс валют
на 10 Дек 2024 г.
704 - Вьетнамских донгов
- 1