- •Тема 1 Основы cgi-программирования
- •1.1 Методы передачи данных
- •1.2 Передача документа пользователю
- •1.3 Передача информации cgi-сценарию
- •Тема 2 Характеристика языка php
- •2.1 Принцип работы php
- •2.2 Переменные, константы, выражения
- •Тема 3 Работа с данными формы
- •3.1 Передача данных
- •3.2 Трансляция полей формы в переменные
- •Тема 4 Конструкции языка
- •4.1 Условные инструкции
- •4.2 Инструкции циклов
- •4.3 Инструкции включения
- •Тема 5 Ассоциативные массивы
- •5.1 Списки и ассоциативные массивы
- •5.2 Операции над массивами
- •5.3 Списки и строки
- •5.4 Сериализация
- •Тема 6 Работа с массивами
- •6.1 Сортировка массивов
- •6.2 Функции для работы с массивами
- •Тема 7 Функции и области видимости
- •7.1 Формат определения функции, передача параметров
- •7.2 Глобальные, локальные, статические переменные
- •7.3 Рекурсия, вложенные и условно-определяемые функции
- •7.4 Передача функций по ссылке и возврат функцией ссылки
- •Тема 8 Строковые функции
- •8.1 Функции работы со строками
- •8.2 Работа с блоками текста
- •Тема 9 Математические функции
- •9.1 Встроенные константы
- •9.2 Встроенные функции
- •Тема 10 Работа с файлами и каталогами,
- •10.1 Функции работы с файлами
- •10.2 Блокирование файла
- •10.3 Функции работы с каталогами
- •10.4 Запуск внешних программ
- •Тема 11 Работа с датами и временем,
- •11.1 Представление времени в формате timestamp
- •11.2 Работа с датами, григорианский календарь
- •11.3 Посылка писем через php
- •Тема 12 Работа с www
- •12.1 Установка заголовков ответа
- •12.2 Работа с Cookies
- •Тема 13 Управление интерпретатором
- •13.1 Управление интерпретатором
- •13.2 Управление сессиями
- •Тема 14 Работа с базой данных mysql
- •14.1 Соединение с базой данных
- •14.2 Выполнение запросов к базе данных
- •Тема 15 Загрузка файлов на сервер
- •15.1 Multipart-формы, тег выбора файла
- •15.2 Поддержка закачки в php
- •Учебное издание
- •Разработка программного обеспечения на платформе net: php.Net
- •246019 Г. Гомель, ул. Советская, 104
12.2 Работа с Cookies
Термин Cookies (это множественное число, произносится как «кукис» или «куки»). В буквальном переводе слово звучит как «печенье», и почему компания Netscape так назвала свое изобретение, неизвестно. Слово Cookies применяется с большой буквы, во множественном числе и мужского рода. В единственном числе это понятие записывается Cookie и произносится на русский манер – «кука».
Cookie – это небольшая именованная порция информации, которая может сохраняться в настройках браузера пользователя между сеансами. Причина, по которой применяются Cookies – большое количество посетителей сервера, а также нежелание иметь нечто подобное базе данных для хранения информации о каждом посетителе. Поиск в такой базе может очень и очень затянуться, и, в то же время, нет никакого смысла централизованно хранить столь отрывочные сведения. Использование Cookies фактически перекладывает задачу на плечи браузера, решая одним махом как проблему быстродействия, так и проблему большого объема базы данных с информацией о пользователе.
Самый распространенный пример применения Cookies – логин и пароль пользователя, использующего защищенные ресурсы сайта. Эти данные, между открытиями страниц хранятся в Cookies, для того чтобы пользователю не пришлось их каждый раз набирать заново.
У каждого Cookie есть определенное время жизни, по истечение которого он автоматически уничтожается. Существуют также Cookies, которые «живут» только в течение текущего сеанса работы с браузером (это могут быть, например, имя и пароль, введенные при авторизации), или же идентификатор сессии.
Каждый Cookie устанавливается сценарием на сервере. Сценарий также получает все Cookies, которые сохранены на удаленном компьютере, при каждом своем запуске, так что он может в любой момент времени узнать, что же у пользователя установлено. Для этого он должен послать браузеру специальный заголовок вида:
Set-cookie: данные
Кроме этого, имеется также информация об имени сервера, установившего этот Cookie, и URL каталога, в котором находился сценарий-хозяин в момент инициализации. Имя сервера и каталог нужны для следующего: сценарию передаются только те Cookies, у которых параметры с именем сервера и каталога совпадают соответственно с хостом и каталогом сценария. Поэтому невозможно получить доступ к «чужим» Cookies – браузер просто не будет посылать их серверу.
Однако в PHP этот процесс скрыт за функцией SetCookie().
Недостатки Cookies. Первый – не все браузеры поддерживают Cookies. Второй недостаток заключается в том, что каждый браузер хранит свои Cookies отдельно. То есть Cookies, установленные при пользовании Internet Explorer, не будут «видны» при работе в Netscape, и наоборот.
Установка Cookie. Команда установки Cookie – это просто один из заголовков ответа, передаваемых сервером браузеру. То есть, перед тем как выводить Content-type, можно указать некоторые команды для установки Cookie. Формат команды (как и всякий заголовок, записывается она в одну строку):
Set-Cookie: name=value; expires=дата;
domain=имя_хоста; path=путь; secure
Существует и другой подход активизировать Cookie – при помощи HTML-тэга <meta>. Формат тэга:
<meta http-equiv="Set-Cookie"
content="name=value; expires=дата;
domain=имя_хоста; path=путь; secure">
Параметры Cookie:
name – имя, закрепленное за Cookie. Имя должно быть URL-кодированным текстом, т. е. состоять только из алфавитно-цифровых символов.
value – текст, который будет рассматриваться как значение Cookie. “тот текст должен быть URL-кодирован.
expires – необязательная пара expires=дата задает время жизни Cookie. Cookie самоуничтожится, как только наступит указанная дата. Например, если задать expires=Friday,31-Dec-09 23:59:59 GMT, то «печенье» будет «жить» только до 31 декабря 2009 года. Если этот параметр не указан, то временем жизни будет считаться вся текущая сессия работы браузера, до того момента, как пользователь его закроет.
domain – параметр domain=имя_хоста задает имя хоста, с которого установили Cookie. Его можно менять вручную, прописав нужный адрес, и таким образом «подарить» Cookie другому хосту. Только в том случае, если параметр не задан, имя хоста определяется браузером автоматически.
path – параметр path=путь описывает каталог (точнее, URI), в котором расположен сценарий, установивший Cookie. Этот параметр также можно установить вручную, записав в него не только каталог, а вообще все, что угодно. Однако указав хост, отличный от хоста сценария, или путь, отличный от URI каталога (или родительского каталога) сценария, тем самым никогда больше не увидим Cookie в этом сценарии.
secure – параметр связан с защищенным протоколом передачи HTTPS. Он используется при написании сценария для проведения банковских операций с кредитными карточками (или иные, требующие повышенной безопасности).
Значения всех параметров Cookie должны быть URL-кодированы.
Получение Cookies из браузера. Все Cookies хранятся в переменной окружения HTTP_COOKIE в таком же формате, как и QUERY_STRING, только вместо & используется ;. Например, если установили два Cookies: cookie1=value1 и cookie2=value2, то в переменной окружения HTTP_COOKIE будет следующее:
cookie1=value1;cookie2=value2.
Сценарий должен разобрать эту строку, распаковать ее и затем работать по своему усмотрению.
Установка Cookie в PHP. Так как Cookie фактически представляет собой обычный заголовок, сделать это можно только перед первой командой вывода в сценарии.
int setcookie(string $name [,string $value] [,int $expire][,string $path] [,string $domain] [,book $secure])
Вызов SetCookie() определяет новый Cookie, который тут же посылается браузеру вместе с остальными заголовками. Все аргументы, кроме имени, необязательны. Если задан только параметр $name (имя Cookie), то Cookie с указанным именем у пользователя удаляется. Можно пропускать аргументы, которые не нужно задавать, заменяя их пустыми строками "". Аргументы $expire и $secure, не могут быть представлены строками, а потому вместо пустых строк здесь нужно использовать 0. Параметр $expire задает timestamp, который, например, может быть сформирован функциями time() или mktime(). Параметр $secure говорит о том, что величина Cookie может передаваться только через безопасное HTTPS-соединение.
Примеры использования SetCookie():
// Cookie на одну сессию, т. е. до закрытия браузера
SetCookie("TestCookie","Test Value");
// Эти Cookies уничтожаются браузером через 1 час после установки
SetCookie("TestCookie",$val,time()+3600);
SetCookie("TestCookie",$val,time()+3600,
"/~rasmus/",".utoronto.ca",1);
После вызова функции SetCookie() только что созданный Cookie сразу появляется среди глобальных переменных как переменная с заданным в параметре $name именем. Она появится и при следующем запуске сценария – даже если SetCookie() в нем и не будет вызвана. Параметр $value автоматически URL-кодируется при посылке на сервер, а при получении Cookie – автоматически декодируется, как это происходит и с данными формы.
Пример: счетчик посещения страницы конкретным посетителем. Запуская данный сценарий, пользователь будет видеть, сколько раз он уже гостил на странице.
Индивидуальный счетчик посещений:
if(!isSet($Counter)) $Counter=0;
$Counter++;
SetCookie("Counter",$Counter,0x7FFFFFFF);
echo "Вы запустили этот сценарий $Counter раз!";
Если понадобится сохранять в Cookies не только строки, но и сложные объекты, то объект нужно сначала преобразовать в строку (например, при помощи Serialize()) и поместить ее в Cookie. А потом, наоборот, распаковать строку, используя Unserialize(). Если сохраняемый массив имеет небольшой размер, каждый его элемент можно разместить в отдельном Cookie:
SetCookie("Arr[0]","aaa");
SetCookie("Arr[1]","bbb");
SetCookie("Arr[2][0]","ccc"); // многомерный массив
По сути, Cookie с именем Arr[0] ничем не отличается с точки зрения браузера и сервера от обычного Cookie. Зато PHP, получив Cookie с именем, содержащим квадратные скобки, поймет, что это на самом деле элемент массива, и создаст его (массив).
В большинстве браузеров число Cookies, которые могут быть установлены одним сервером, ограничено, причем ограничено именно их количество, а не суммарный объем. Поэтому лучше будет воспользоваться функцией Serialize() и установить один Cookie.
Получение Cookie в PHP. Предположим, сценарий отработал и установил какой-то Cookie, например, с именем Cook и значением Val. В следующий раз при запуске этого сценария ему передастся пара типа Cook=Val (через специальную переменную окружения). PHP это событие перехватит и автоматически создаст переменную $Cook со значением Val. То есть интерпретатор действует точно так же, как если бы значение Cookie пришло из формы. Та переменная, которую установили в прошлый раз, будет доступна и сейчас!
Авторизация. Часто бывает нужно, чтобы на какой-то URL могли попасть только определенные пользователи. А именно, только те, у которых есть зарегистрированное имя (login) и пароль (password). Механизм авторизации призван упростить проверку данных таких пользователей. Рассмотрим один из самых простых типов авторизации – basic-авторизацию. Предположим, что сценарий посылает браузеру пользователя следующий заголовок:
WWW-Authenticate: Basic realm="имя_зоны"
HTTP/1.0 401 Unauthorized"
Строка имя_зоны задает идентификатор, который будет определять, к каким ресурсам будет разрешен доступ зарегистрированным пользователям. При программировании CGI-сценариев этот параметр используется в основном для формирования приветствия (подсказки) в диалоговом окне, появляющемся в браузере пользователя (там отображается имя зоны).
Затем посылается тело документа. В браузере пользователя появляется диалоговое окно, в котором предлагается вести login и password. После того как пользователь это сделает, управление передается обратно серверу, который среди обычных заголовков запроса получает примерно такой:
Authorization: Basic TG9naW46UGFzcw==
Это закодированные данные, введенные пользователем. Далее этот заголовок должен передаться сценарию. Сценарий, декодировав его, может решить: то ли повторить всю процедуру сначала (если имя или пароль неправильные), или же начать работать с сообщением «OK, все в порядке, вы – зарегистрированный пользователь».
Предположим, что сценарий подтвердил верность данных и «пропустил» пользователя. В этом случае происходит еще одна вещь: login и password пользователя запоминаются в скрытом Cookie, «живущем» в течение одной сессии работы с браузером. Затем, заголовок
Authorization: Basic значение_Cookie
будет присылаться для любого сценария (и даже для любого документа) на сервере. Таким образом, посетителю, зарегистрировавшемуся однажды, нет необходимости каждый раз заново набирать свое имя и пароль в течение текущего сеанса работы с браузером, т. е., пока пользователь его не закроет.
После верной авторизации при вызове любого сценария будет установлена переменная окружения REMOTE_USER, содержащая имя пользователя.
SSI и функция virtual(). Для одного и того же документа в Apache нельзя применять два «обработчика». Иными словами, действует принцип: либо PHP, либо SSI (Server-Side Includes – включения на стороне сервера). Однако в PHP имеются определенные средства для «эмуляции» SSI-конструкции
include virtual
Конструкция include virtual загружает файл, URL которого указан у нее в параметрах, обрабатывает его нужным обработчиком и выводит в браузер. То есть все происходит так, будто указанный URL был затребован виртуальным браузером. Большинство SSI-файлов ограничиваются использованием этой возможности.
int virtual(string $url)
Функция virtual() представляет собой процедуру, которая может поддерживаться только в случае, если PHP установлен как модуль Apache. Она делает то же самое, что и SSI-инструкция <!--#include virtual=...-->, т.е. она генерирует новый запрос серверу, обрабатываемый им обычным образом, а затем выводит данные в стандартный поток вывода.
Чаще всего функция virtual() используется для запуска внешних CGI-сценариев, написанных на другом языке программирования, или же для обработки SSI-файлов более сложной структуры. Для включения обычных PHP-файлов с участками кода функция virtual() неприменима – это выполняет оператор include.
