Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Котеров Д. В., Костарев А. Ф. - PHP 5. 2-е издание (В подлиннике) - 2008

.pdf
Скачиваний:
6286
Добавлен:
29.02.2016
Размер:
11.36 Mб
Скачать

74

Часть I. Основы Web-программирования

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

Установка cookie

Мы подошли к вопросу: как же сценарий может установить cookie в браузере пользователя? Ведь он работает "на одном конце провода", а пользователь — на другом. Решение довольно логично: команда установки cookie — это просто один из заголовков ответа, передаваемых сервером браузеру. То есть, перед тем как выводить Content-type, мы можем указать некоторые команды для установки cookie. Выглядит такая команда следующим образом (разумеется, как и всякий заголовок, записывается она в одну строку):

Set-Cookie: name=value; expires=дата; domain=имя_хоста; path=путь; secure

Существует и другой подход активизировать cookie — при помощи HTML-тега <meta>. Соответственно, как только браузер увидит такой тег, он займется обработкой cookie. Формат тега следующий:

<meta

http-equiv="Set-Cookie"

content="name=value; expires=дата; domain=имя_хоста; path=путь; secure"

>

Мы можем видеть, что даже названия параметров в обоих способах одинаковы. Какой из них выбрать — решать вам: если все заголовки уже выведены к тому моменту, когда вам потребовалось установить cookie, используйте тег <meta>. В противном случае лучше взять на вооружение заголовки, т. к. они не видны пользователю, а чем пользователь меньше видит при просмотре исходного текста страницы в браузере — тем лучше нам, программистам.

Возможно, вы спросите, нахмурив брови: "Что же, с точки зрения программиста хороший пользователь — слепой пользователь?" Тогда мы ответим: "Что вы, нет и еще раз нет! Такой пользователь хорош лишь для дизайнера, для программиста же желателен пользователь безрукий (или, по крайней мере, лишенный клавиатуры и мыши)".

Вот что означают параметры cookie.

name

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

value

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

Глава 3. CGI изнутри

75

expires

Необязательная пара expires=дата задает время жизни нашего cookie. Точнее, cookie самоуничтожится, как только наступит указанная дата. Например, если задать

expires=Sunday, 2-Feb-03 15:52:00 GMT

то "печенье" будет "жить" только до 2 февраля 2003 года. Кстати, вот вам и вторая неприятность: хорошо, если мы знаем наверняка время "смерти" cookie. А если нам нужно его вычислять на основе текущего времени (например, если мы хотим, чтобы cookie существовал 10 дней после его установки, как в подавляющем большинстве случаев и происходит)? Придется использовать функцию, которая формировала бы календарную дату в указанном выше формате. Кстати, если этот параметр не указан, то временем жизни будет считаться вся текущая сессия работы браузера, до того момента, как пользователь его закроет.

domain

Параметр domain=имя_хоста задает имя хоста, с которого установили cookie. Ранее мы уже говорили про этот параметр. Так вот, оказывается, его можно менять вручную, прописав здесь нужный адрес, и таким образом "подарить" cookie другому хосту. Только в том случае, если параметр не задан, имя хоста определяется браузером автоматически.

path

Параметр path=путь обычно описывает каталог (точнее, URI), в котором расположен сценарий, установивший cookie. Как мы видим, этот параметр также можно задать вручную, записав в него не только каталог, а вообще все, что угодно. Однако при этом следует помнить: указав хост, отличный от хоста сценария, или путь, отличный от URI каталога (или родительского каталога) сценария, мы тем самым никогда больше не увидим наш cookie в этом сценарии.

secure

Этот параметр связан с защищенным протоколом передачи HTTPS, который в книге не рассматривается. Если вы не собираетесь писать сценарии для проведения банковских операций с кредитными карточками (или иные, требующие повышенной безопасности), вряд ли стоит обращать на него внимание.

После запуска сценария, выводящего соответствующий заголовок (или тег <meta>), у пользователя появится cookie с именем name и значением value. Еще раз напоминаем: значения всех параметров cookie должны быть URL-кодированы, в противном случае возможны неожиданности.

Получение cookies из браузера

Получить cookies для сценария несколько проще: все они хранятся в переменной окружения HTTP_COOKIE в таком же формате, как и QUERY_STRING, только вместо символа & используется ;. Например, если мы установили два cookies: cookie1=value1 и cookie2=value2, то в переменной окружения HTTP_COOKIE будет следующее:

cookie1=value1;cookie2=value2

Сценарий должен разобрать эту строку, распаковать ее и затем работать по своему усмотрению.

76 Часть I. Основы Web-программирования

Пример программы для работы с cookies

В заключение приведем простой сценарий, который использует cookies (листинг 3.8). Для упрощения в нем не производится URL-кодирование и декодирование — будем считать, что пользователь может печатать только на латинице.

Листинг 3.8. Файл c/cookies.c

//Простой сценарий, использующий cookies. #include <stdio.h>

#include <stdlib.h>

//начало программы

void main() {

//временный буфер char Buf[1000];

//получаем в переменную Cook значение Cookies char *Cook = getenv("HTTP_COOKIE");

//пропускаем в ней 5 первых символов ("cook="), если она не пустая -

//получим как раз значение cookie, которое мы установили ранее

//(см. ниже).

Cook += 5; // сдвинули указатель на 5 символов вперед по строке

//получаем переменную QUERY_STRING char *Query = getenv("QUERY_STRING");

//проверяем, заданы ли параметры у сценария — если да, то

//пользователь, очевидно, ввел свое имя или нажал кнопку,

//в противном случае он просто запустил сценарий без параметров if(strcmp(Query, "")) { // строка не пустая?

//копируем в буфер значение QUERY_STRING,

//пропуская первые 5 символов (часть "name=") -

//получим как раз текст пользователя

strcpy(Buf, Query + 5);

//пользователь ввел имя — значит, нужно установить cookie printf("Set-cookie: cook=%s; "

"expires=Sunday, 2-Feb-03 15:52:00 GMT", Buf);

//Теперь это новое значение cookie

Cook=Buf;

}

//выводим страницу с формой printf("Content-type: text/html\n\n"); printf("<html><body>\n");

//если имя задано (не пустая строка), приветствие if(strcmp(Cook, ""))

printf("<h1>Привет, %s!</h1>\n",Cook);

//продолжаем

printf("<form action=/cgi-bin/script.cgi method=get>\n"); printf("Ваше имя: ");

printf("<input type=text name=name value='%s'>\n",Cook); printf("<input type=submit value='Отправить'>\n"); printf("</form>\n");

printf("</body></html>");

}

Глава 3. CGI изнутри

77

Теперь при первом заходе на этот URL пользователь получит форму с пустым полем для ввода имени. Если он что-то туда напечатает и нажмет кнопку отправки, его информация запомнится браузером. Итак, посетив в любое время до 2 февраля 2003 г. этот же URL, он увидит то, что напечатал давным-давно в текстовом поле. И, что самое важное, — его информацию "увидит" также и сценарий. Кстати, у злоумышленника нет никаких шансов получить значение cookie посетителя, потому что оно хранится у него на компьютере, а не на сервере.

И опять мы намекаем на то, что использование языка C и на этот раз довольно затруднительно. Неудобно URL-декодировать и кодировать данные при установке cookies, накладно разбирать их на части, да и вообще наша простая программа получилась слишком длинной. Не правда ли, приятно будет обнаружить, что в PHP все это реализовано автоматически: для работы с cookies существует всего одна универсальная функция SetCookie(), а получение cookies от браузера вообще не вызовет никаких проблем, потому что оно ничем не отличается от получения данных формы. Это логично. В самом деле, какая нам разница, какие данные пришли из формы, а какие — из cookies? С точки зрения сценария — все равно...

Но не будем забегать вперед. Займемся пока теорией авторизации.

Авторизация

Часто бывает нужно, чтобы на какой-то URL могли попасть только определенные пользователи. А именно только те, у которых есть зарегистрированное имя (login) и пароль (password). Механизм авторизации как раз и призван упростить проверку данных таких пользователей.

Мы не будем здесь рассматривать все возможности этого механизма по трем причинам. Во-первых, существует довольно много типов авторизации, различающихся степенью защищенности передаваемых данных. Во-вторых, при написании обычных CGI-сценариев для того, чтобы включить механизм авторизации, необходимо провести некоторые манипуляции с настройками (файлами конфигурации) сервера, что, скорее всего, будет затруднительно (ведь обычно компания, которая предоставляет услуги по обслуживанию виртуального хоста, не позволяет вмешиваться в настройки сервера). И наконец, в-третьих, весь механизм авторизации значительно упрощается и унифицируется при использовании PHP, и вам не придется ничего исправлять в этих злополучных настройках сервера. Так что давайте отложим практическое знакомство с авторизацией и займемся ее теорией.

Расскажем вкратце о том, как все происходит на нижнем уровне при одном из самых простых типов авторизации — basic-авторизации. Итак, предположим, что сценарий посылает браузеру пользователя следующий заголовок:

WWW-Authenticate: Basic realm="имя_зоны"

HTTP/1.0 401 Unauthorized

Обратите внимание, что последний заголовок несколько отличается по форме от обычных заголовков. Так и должно быть. Строка имя_зоны в первом из них задает некоторый идентификатор, определяющий, к каким ресурсам будет разрешен доступ зарегистрированным пользователям. При программировании CGI-сценариев этот параметр используется в основном исключительно для формирования приветствия

78

Часть I. Основы Web-программирования

(подсказки) в диалоговом окне, появляющемся в браузере пользователя (там отображается имя зоны).

Затем, как обычно, посылается тело документа (сразу отметим, что именно это тело ответа будет выдано пользователю, если он нажмет в диалоговом окне кнопку Cancel, т. е. отменит вход). В этом случае происходит нечто удивительное: в браузере пользователя появляется небольшое диалоговое окно, в котором предлагается ввести зарегистрированное имя и пароль. После того как пользователь это сделает, управление передается обратно серверу, который среди обычных заголовков запроса (посылаемых браузером) получает примерно такой:

Authorization: Basic TG9naW46UGFzcw==

Это не что иное, как закодированные данные, введенные пользователем. Теоретически, далее этот заголовок должен каким-то образом передаться сценарию (для этого как раз и необходимо добавление команд в файлы конфигурации сервера). Сценарий, декодировав его, может решить: или повторить всю процедуру сначала (если имя или пароль неправильные), или же начать работать с сообщением "OK, все в порядке, Вы — зарегистрированный пользователь".

Предположим, что сценарий подтвердил верность данных и "пропустил" пользователя. В этом случае происходит еще одна вещь: login и password пользователя запоминаются в скрытом cookie, "живущем" в течение одной сессии работы с браузером. Затем, что бы мы ни делали, заголовок

Authorization: Basic значение_cookie

будет присылаться для любого сценария (и даже для любого документа) на нашем сервере. Таким образом, посетителю, зарегистрировавшемуся однажды, нет необходимости каждый раз заново набирать свое имя и пароль в течение текущего сеанса работы с браузером, т. е. пока пользователь его не закроет.

И еще: после верной авторизации при вызове любого сценария будет установлена переменная окружения REMOTE_USER, содержащая имя пользователя. Так что в дальнейшем можно ее задействовать для определения, какой же посетитель зарегистрировался.

Резюме

В данной главе мы рассказали о том, как "работает" интерфейс CGI на низком уровне и рассмотрели все основные способы обработки и передачи данных, применяемые сценариями. Мы научились оперировать различными элементами форм и запускать сценарии, отправляя им введенные данные. Кратко рассмотрели основы работы с cookies, формат multipart-данных, предназначенный для передачи бинарных файлов на сервер, а также вопросы авторизации.

Приходится признать, что глава содержит достаточно много материала, весьма сложного для начинающего. Если вы мало что поняли после ее прочтения, не отчаивайтесь, а просто читайте дальше. Через некоторое время, попрактиковавшись в PHP, вы сможете вернуться к данной главе и взглянуть на нее другими глазами. Естественно, в следующих главах книги многие темы будут затронуты вновь, но рассмотрены уже с новой точки зрения — с точки зрения PHP.

ЧАСТЬ II

Выбор и настройка инструментария

Глава 4. Установка Apache

Глава 5. Установка PHP и MySQL

Глава 6. Денвер: автоматизация установки инструментария

Глава 7. Установка PHP 5 в ОС Unix

ГЛАВА 4

Установка Apache

Листинги данной главы можно найти в подкаталоге WebServers.

Как уже неоднократно упоминалось ранее, для того чтобы разрабатывать и отлаживать скрипты, вам понадобится хостинг, а значит, работающий Web-сервер и, возможно, какая-нибудь СУБД. Часть книги, которой принадлежит данная глава, как раз и посвящена выбору и настройке инструментария, который вам пригодится. Также в ней описывается подход, который позволит сделать разработку сайтов максимально комфортной и быстрой — по крайней мере, с технической стороны.

Вероятно, чтобы продолжить, вам придется скачать из Интернета не один мегабайт дистрибутивов различных программ и утилит. Без них вряд ли получится комфортная работа. Так что приготовьтесь к этому.

Традиционный процесс отладки сайта

Наша задача — сделать процесс отладки (который, по прикидкам, может занимать до 80% времени разработчика) максимально комфортным. Рутине не место в профессии программиста. Сегодня, в 2004 году, отладка скриптов в большинстве случаев все еще ведется по старому принципу:

1.Сначала программы копируются на сервер по протоколу FTP.

2.Затем разработчик открывает нужную страницу в браузере, видит сообщение об ошибке или же какой-то диагностический вывод, который он заставил скрипт сделать.

3.Ошибка исправляется, а также, возможно, добавляется еще пара диагностических операторов.

4.Далее процесс повторяется, начиная с первого пункта: снова выполняются копирование, проверка, исправление...

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

82

Часть II. Выбор и настройка инструментария

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

Вы также зададитесь вопросом, к какой хостинг-компании обратиться, чтобы приобрести дешевую, но в то же время надежную платформу для разработки. Она должна быть доступна 24 часа в сутки: представьте, что в один прекрасный момент вы поняли, где ошибка, исправили ее, начинаете закачивать файлы на сервер... а они не закачиваются. Пока сервер восстановят, вы уже успеете потерять свою мысль.

Есть люди, которые используют такой подход многие годы. Но разве этот процесс отладки можно назвать комфортным?

Локальный сервер

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

Текущая машина всегда доступна по IP-адресу 127.0.0.1, что эквивалентно доменному имени localhost. Соответственно, для доступа к локальному Web-серверу через браузер вам нужно будет использовать адрес http://localhost.

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

В данном подходе есть только одна небольшая проблема. Вы, вероятнее всего, работаете в Windows, а следовательно, и локальный Web-сервер будет работать в этой ОС. В то же время, на сервере хостера обычно установлена ОС Unix. Как вы знаете, данные системы довольно сильно различаются, и это многих отпугивает.

Действительно, можно ли (и удобно ли) разрабатывать и отлаживать скрипты в Windows, а потом безо всяких изменений переносить их в Unix? К счастью, ответ на этот вопрос — да, можно, и да, удобно! В этой и следующих двух главах вы найдете подробные инструкции и рекомендации.

Почему Apache?

В дальнейшем мы будем придерживаться подхода с использованием локального Web-сервера Apache для Windows, запущенного на вашей рабочей машине. Мы также установим PHP и MySQL, способные работать в этой ОС.

Почему именно Apache? Дело в том, что это самый распространенный на данный момент сервер, и вряд ли в ближайшие несколько лет он потеряет свою популярность. Он установлен у большинства хостинг-провайдеров. Кроме того, что немало-

Глава 4. Установка Apache

83

важно, существует его Windows-версия, практически идентичная по функциональности своему Unix-собрату.

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

Даже если вы и не планируете в будущем использовать PHP, а предпочитаете другой язык (например, Perl), то после внимательного ознакомления с этой частью книги сможете упростить себе жизнь — точнее, ее часть, касающуюся написания и отладки сценариев. И это благодаря тому, что все описанное здесь почти на 100% совместимо с тем программным обеспечением, которое скорее всего установлено у вашего хостинг-провайдера (а больше половины современных хостинг-провайдеров работают с Unix, но не с Windows).

От слов к делу: установка Apache

Итак, вы решились установить на свой компьютер Apache для Windows. В таком случае вам следует запастись терпением и для начала скачать дистрибутив сервера с официального сайта Apache.

Получение дистрибутива

Вот точная ссылка на каталог, в котором расположены несколько последних версий Apache: http://www.apache.org/dist/httpd/binaries/win32/. Вам нужен EXE-файл, имя которого содержит подстроку no_src, т. е. "без исходных кодов".

Рекомендуем устанавливать самую последнюю версию Apache серии 1.3.x, но не Apache 2.0.x! Дело в том, что версия 2.0 все еще не очень стабильна и плохо работает в Windows. Кроме того, с ней возможны проблемы при установке PHP. Сейчас (октябрь 2004 года) наиболее предпочтительная версия Apache — 1.3.31, она многократно проверена и работает в Windows без каких-либо особенностей.

Получение документации

Конфигурирование Apache — довольно непростое занятие. К счастью, все директивы сервера подробно описаны в сопроводительной документации, включенной в дистрибутив, который вы только что скачали. Правда, она на английском языке.

Существует и online-версия руководства. Она доступна по адресу http://httpd.apache.org /docs/. Главное достоинство документации на сайте в том, что по ней можно проводить поиск, что недоступно при использовании руководства из дистрибутива.

Теперь нам предстоит настройка Apache для вашей системы.