Лекция №2

 

Лекция №2

Основи клієнт-серверних технологій, Протокол HTTP і способи передачі даних на сервер, Використання HTML-форм для передачі даних на сервер,Обробка запитів за допомогою PHP, Суперглобальні масиви, PHP і Cookies, Робота з сесією

Основи клієнт-серверних технологій

PHP - це скриптова мова, оброблювана сервером. Якщо мова йде про сервер, мимоволі спливає в пам'яті поняття клієнта. Все тому, що ці два поняття нерозривно пов'язані. Об'єднує їх комп'ютерна архітектура клієнт-сервер. Зазвичай, коли говорять «сервер», мають на увазі сервер в архітектурі клієнт-сервер, а коли говорять «клієнт» - мають на увазі клієнт в цій же архітектурі. Так що ж це за архітектура? Суть її в тому, щоб розділити функції між двома підсистемами: клієнтом, який відправляє запит на виконання будь-яких дій, і сервером, який виконує цей запит. Взаємодія між клієнтом і сервером відбувається за допомогою стандартних спеціальних протоколів, таких як TCP / IP. Насправді протоколів дуже багато, вони розрізняються за рівнями. Ми розглянемо тільки протокол прикладного рівня HTTP (трохи пізніше), оскільки для вирішення наших програмістських завдань потрібен тільки він. А поки повернемося до клієнт-серверної архітектури і розберемося, що ж таке клієнт і що таке сервер.

Сервер являє собою набір програм, які контролюють виконання різних процесів. Відповідно, цей набір програм встановлений на якомусь комп'ютері. Часто комп'ютер, на якому встановлено сервер, і називають сервером. Основна функція комп'ютера-сервера - по запиту клієнта запустити який-небудь певний процес і відправити клієнту результати його роботи.

Клієнтом називають будь-який процес, який користується послугами сервера. Клієнтом може бути як користувач, так і програма. Основне завдання клієнта - виконання програми та здійснення зв'язку з сервером, коли цього потребує програма. Тобто клієнт повинен надавати користувачеві інтерфейс для роботи з додатком, реалізовувати логіку його роботи і при необхідності відправляти завдання серверу.

Взаємодія між клієнтом і сервером починається з ініціативи клієнта. Клієнт запитує вид обслуговування, встановлює сеанс, отримує потрібні йому результати і повідомляє про закінчення роботи.

Послугами одного сервера найчастіше користується декілька клієнтів одночасно. Тому кожен сервер повинен мати досить велику продуктивність і забезпечувати безпеку даних.

Логічно встановлювати сервер на комп'ютері, що входить в яку-небудь мережу, локальну або глобальну. Однак можна встановлювати сервер і на окремому комп'ютері (тоді він буде одночасно і клієнтом і сервером).

Існує безліч типів серверів. Ось лише деякі з них.

  • Відеосервер 
    Такий сервер спеціально пристосований до обробки зображень, зберігання відеоматеріалів, відеоігор і т.п. У зв'язку з цим комп'ютер, на якому встановлений відеосервер, повинен мати високу продуктивність і велику пам'ять.
  • Пошуковий сервер призначений для пошуку інформації в Internet.
  • Поштовий сервер надає послуги у відповідь на запити, надіслані електронною поштою.
  • Сервер WWW призначений для роботи в Internet.
  • Сервер баз даних виконує обробку запитів до баз даних.
  • Сервер захисту даних призначений для забезпечення безпеки даних (містить, наприклад, засоби для ідентифікації паролів).
  • Сервер додатків призначений для виконання прикладних процесів. З одного боку взаємодіє з клієнтами, одержуючи завдання, а з іншого - працює з базами даних, підбираючи необхідні для обробки дані.
  • Сервер віддаленого доступу забезпечує колективний віддалений доступ до даних.
  • Файловий сервер забезпечує функціонування розподілених ресурсів, надає послуги пошуку, зберігання, архівування даних і можливість одночасного доступу до них декількох користувачів.

Зазвичай на комп'ютері-сервері працює відразу кілька програм-серверів. Одна займається електронною поштою, інша розподілом файлів, третя rjynhjk.’ web-сторінки.

З усіх типів серверів нас в основному цікавить сервер WWW. Часто його називають web-сервером, http-сервером або навіть просто сервером. Що являє собою web-сервер? По-перше, це сховище інформаційних ресурсів. По-друге, ці ресурси зберігаються і надаються користувачам відповідно до стандартів Internet (такими, як протокол передачі даних HTTP). Як надаються дані у відповідності з цим протоколом, ми розглянемо трохи пізніше. Робота з документами web-сервера здійснюється за допомогою браузера (наприклад, IE, Opera або Mozilla), який відсилає серверу запити, створені відповідно до протоколу HTTP. У процесі виконання завдання сервер може зв'язуватися з іншими серверами.

В якості прикладів web-серверів можна навести сервер Apache групи Apache, Internet Information Server (IIS) компанії Microsoft, SunOne фірми Sun Microsystems, WebLogic фірми BEA Systems, IAS (Inprise Application Server) фірми Borland, WebSphere фірми IBM, OAS (Oracle Application Server ).

Все, що ми коли-небудь будемо говорити о web-серверах, орієнтоване на Apache, якщо не вказано інший. А тепер, як було обіцяно, звернемося до протоколу HTTP.

Протокол HTTP і способи передачі даних на сервер

Internet побудований за багаторівневим принципом, від фізичного рівня, пов'язаного з фізичними аспектами передачі двійкової інформації, і до прикладного рівня, що забезпечує інтерфейс між користувачем і мережею.

HTTP (HyperText Transfer Protocol, протокол передачі гіпертексту) - це протокол прикладного рівня, розроблений для обміну гіпертекстової інформацією в Internet.

HTTP надає набір методів для вказівки цілей запиту, що відправляється серверу. Ці методи основані на узгодженості посилань, де для вказівки ресурсу, до якого має бути застосований даний метод, використовується універсальний ідентифікатор ресурсів (Universal Resource Identifier) у вигляді місцезнаходження ресурсу (Universal Resource Locator, URL) або у вигляді його універсального імені (Universal Resource Name , URN).

Повідомлення по мережі при використанні протоколу HTTP передаються у форматі, схожому з форматом поштового повідомлення Internet (RFC-822) або з форматом повідомлень MIME (Multipurpose Internet Mail Exchange).

HTTP використовується для комунікацій між різними користувацькими програмами та програмами-шлюзами, що надають доступ до існуючих Internet-протоколів, таких як SMTP (протокол електронної пошти), NNTP (протокол передачі новин), FTP (протокол передачі файлів), Gopher і WAIS. HTTP розроблений для того, щоб дозволяти таким шлюзам через проміжні програми-сервери (proxy) передавати дані без втрат.

Протокол реалізує принцип запит / відповідь. Запитуюча програма-клієнт ініціює взаємодію з відповідною програмою-сервером, і надсилає запит, який містить:

  • метод доступу;
  • адресу URI;
  • версію протоколу;
  • повідомлення (схоже за формою на MIME) з інформацією про тип переданих даних, інформацією про клієнта, що послав запит, і, можливо, із змістовною частиною (тілом) повідомлення.

Відповідь сервера містить:

  • рядок стану, в яку входить версія протоколу і код повернення (успіх або помилка);
  • повідомлення (у формі, схожій на MIME), до якого входить інформація сервера, метаінформація (тобто інформація про зміст повідомлення) і тіло повідомлення.

У протоколі не вказується, хто повинен відкривати і закривати з'єднання між клієнтом і сервером. На практиці з'єднання, як правило, відкриває клієнт, а сервер після відправки відповіді ініціює його розриває.

Форма запиту клієнта

Клієнт відсилає серверу запит в одній з двох форм: у повній або скороченій. Запит у першій формі називається відповідно повним запитом, а в другій формі - простим запитом.

Простий запит містить метод доступу та адресу ресурсу. Формально це можна записати так:

<Простий-Запит>: = <Метод> <символ пробіл> 
<Запитуваний-URI> <символ нового рядка>

В якості методу можуть бути вказані GET, POST, HEAD, PUT, DELETE та інші. Про найбільш поширені з них ми поговоримо трохи пізніше. В якості запитуваної URI найчастіше використовується URL-адреса ресурсу.

Приклад простого запиту: 
GET http://phpbook.info/

Тут GET - це метод доступу, тобто метод, який повинен бути застосований до запитуваного ресурсу, а http://phpbook.info/ - це URL-адреса запитуваного ресурсу.

Повний запит містить рядок стану, кілька заголовків (заголовок запиту, загальний заголовок або заголовок запису) і, можливо, тіло запиту. Формально загальний вигляд повного запиту можна записати так:

<Повний запит>: = <Рядок Стану> 
(<Загальний заголовок> | <Тема запиту> | 
<Заголовок змісту>) 
<Символ нового рядка> 
[<Зміст запиту>]

Квадратні дужки тут позначають необов'язкові елементи заголовка, через вертикальну риску перераховані альтернативні варіанти. Елемент <Рядок стану> містить метод запиту та URI ресурсу (як і простий запит) і, крім того, використовувану версію протоколу HTTP. Наприклад, для виклику зовнішньої програми можна задіяти наступний рядок стану:

POST http://phpbook.info/cgi-bin/test HTTP/1.0

У даному випадку використовується метод POST і протокол HTTP версії 1.0.

В обох формах запиту важливе місце займає URI запитуваного ресурсу. Найчастіше URI використовується у вигляді URL-адреси ресурсу. При зверненні до сервера можна застосовувати як повну форму URL, так і спрощену.

Повна форма містить тип протоколу доступу, адресу сервера ресурсу та адресу ресурсу на сервері (рис 1).

У скороченій формі опускають протокол і адресу сервера, вказуючи лише місце розташування ресурсу від кореня сервера. Повну форму використовують, якщо можливе пересилання запиту іншого сервера. Якщо ж робота відбувається тільки з одним сервером, то частіше застосовують скорочену форму.

 
Рис. 1. Повна форма URL

Методи

Метод повідомляє про мету запиту клієнта. Протокол HTTP підтримує досить багато методів, але реально використовуються тільки три: POST, GET і HEAD. Метод GET дозволяє отримати будь-які дані, ідентифіковані за допомогою URI в запиті ресурсу. Якщо URI вказує на програму, то повертається результат роботи програми, а не її текст (якщо, звичайно, текст не є результат її роботи). Додаткова інформація, необхідна для обробки запиту, вбудовується в сам запит (у рядок статусу). При використанні методу GET у поле тіла ресурсу повертається власне затребувана інформація (текст HTML-документа, наприклад).

Існує різновид методу GET - умовний GET. Цей метод повідомляє серверу про те, що на запит потрібно відповісти, тільки якщо виконуються умови, що міститься в полі if-Modified-Since заголовка запиту. Якщо говорити більш точно, то тіло ресурсу передається у відповідь на запит, якщо цей ресурс змінювався після дати, зазначеної в if-Modified-Since.

Метод HEAD аналогічний методу GET, тільки не повертає тіло ресурсу і не має умовного аналога. Метод HEAD використовують для отримання інформації про ресурс. Це може стати в нагоді, наприклад, при вирішенні завдання тестування гіпертекстових посилань.

Метод POST розроблений для передачі на сервер такої інформації, як анотації ресурсів, новини і поштові повідомлення, дані для додавання в базу даних, тобто для передачі інформації великого обсягу і досить важливої. На відміну від методів GET і HEAD, в POST передається тіло ресурсу, яке і є інформацією, одержану з полів форм або інших джерел введення.

До цих пір ми тільки теоретизували, знайомилися з основними поняттями. Тепер варто навчитися використовувати все це на практиці. Далі в лекції ми розглянемо, як посилати запити серверу і як обробляти його відповіді.

Використання HTML-форм для передачі даних на сервер

Як передавати дані серверу? Для цього в мові HTML є спеціальна конструкція - форми. Форми призначені для того, щоб отримувати від користувача інформацію. Наприклад, вам потрібно знати логін і пароль користувача для того, щоб визначити, на які сторінки сайту його можна допускати. Або вам необхідні особисті дані користувача, щоб була можливість з ним зв'язатися. Форми якраз і застосовуються для введення такої інформації. У них можна вводити текст або вибирати підходящі варіанти зі списку. Дані, записані у форму, відправляються для обробки спеціальною програмою (наприклад, скриптом на PHP) на сервері. Залежно від введених користувачем даних ця програма може формувати різні web-сторінки, відправляти запити до бази даних, запускати різні додатки і т.п.

Розберемося з синтаксисом HTML-форм. Можливо, багато хто з ним знайомий, але ми все ж повторимо основні моменти, оскільки це важливо.

Отже, для створення форми мовою HTML використовується тег FORM. Всередині нього знаходиться одна або декілька команд INPUT. За допомогою атрибутів action і method тега FORM задаються ім'я програми, яка буде обробляти дані форми, і метод запиту, відповідно. Команда INPUT визначає тип і різні характеристики запитуваної інформації. Надсилання даних форми відбувається після натискання кнопки input типу submit. Створимо форму для реєстрації учасників заочної школи програмування.

<h2> Форма для реєстрації учасників </ h2> 
<form action="1.php" method=POST> 

При відправленні запиту буде використаний метод POST -> 
Ім'я <br> <input type = text name = "first_name" 
value = "Ваше ім'я"> <br> 
Прізвище <br> <input type=text name="last_name"> <br> 
E-mail <br> <input type=text name="email"> <br> 
<p> 
Виберіть курс, який ви б хотіли відвідувати: <br> 
<input type=radio name="kurs" value="PHP"> PHP <br> 
<input type=radio name="kurs" value="Lisp"> Lisp <br> 
<input type=radio name="kurs" value="Perl"> Perl <br> 
<input type=radio name="kurs" value="Unix"> Unix <br> 
<P> Що ви хочете, щоб ми знали про вас? <BR> 
<textarea name="comment" cols=32 rows=5> 
<P> <Input name = "confirm" type = checkbox 
checked> Підтвердити отримання <br> 
<input type=submit value="Відправити"> 
<input type=reset value="Відмініти"> 
 

Після обробки браузером цей файл буде виглядати приблизно так:

 
Рис. 1. Приклад html-форми

Ось так створюються і виглядають HTML-форми. Будемо вважати, що ми навчилися чи згадали, як їх створювати. Як ми бачимо, у формі можна вказувати метод передачі даних. Подивимося, що буде відбуватися, якщо вказати метод GET або POST, і в чому буде різниця.

Для методу GET

Для методу GET При відправці даних форми за допомогою методу GET вміст форми додається до URL після знака запитання у вигляді пар імен = значення, об'єднаних за допомогою амперсанда &:

action?name1=value1=name2=value2&name3=value3

Тут action - це URL-адреса програми, яка повинна обробляти форму (це або програма, задана в атрибуті action тега form, або сама поточна програма, якщо цей атрибут опущений). Імена name1, name2, name3 відповідають іменам елементів форми, а value1, value2, value3 - значення цих елементів. Всі спеціальні символи, включаючи = і &, в іменах або значеннях цих параметрів будуть закодовані. Тому не варто використовувати в назвах або значеннях елементів форми ці символи і символи кирилиці в ідентифікаторах.

Якщо в полі для введення ввести який-небудь службовий символ, то він буде переданий в його шістнадцятковому коді, наприклад, символ $ заміниться на% 24. Так само передаються і кирилиця.

Для полів введення тексту і пароля (це елементи input з атрибутом type = text і type = password), значенням буде те, що введе користувач. Якщо користувач нічого не вводить в таке поле, то в рядку запиту буде присутній елемент name =, де name відповідає імені цього елемента форми.

Для кнопок типу checkbox і radio button значення value визначається атрибутом VALUE в тому випадку, коли кнопка відзначена. Не зазначені кнопки при складанні рядка запиту ігноруються повністю. Кілька кнопок типу checkbox можуть мати один атрибут NAME (і різні VALUE), якщо це необхідно. Кнопки типу radio button призначені для одного з усіх запропонованих варіантів і тому повинні мати однаковий атрибут NAME і різні атрибути VALUE.

У принципі створювати HTML-форму для передачі даних методом GET не обов'язково. Можна просто додати рядок URL потрібні змінні та їх значення.

http://phpbook.info/test.php?id=10&user=pit

У зв'язку з цим у передачі даних методом GET є один істотний недолік - будь-хто може підробити значення параметрів. Тому не радимо використовувати цей метод для доступу до захищених паролем сторінок, для передачі інформації, що впливає на безпеку роботи програми або сервера. Крім того, не варто застосовувати метод GET для передачі інформації, яку не дозволено змінювати користувачеві.

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

Для методу POST

Вміст форми кодується точно так само, як для методу GET, але замість додавання рядка до URL вміст запиту надсилається блоком даних як частина операції POST. Якщо присутній атрибут ACTION, то значення URL, яке там знаходиться, визначає, куди посилати цей блок даних. Цей метод, як уже зазначалося, рекомендується для передачі великих за обсягом блоків даних.

Інформація, введена користувачем і відправлена серверу за допомогою методу POST, подається на стандартне введення програми, зазначеної в атрибуті action, чи поточного скрипту, якщо цей атрибут опущений. Довжина посилається файлу передається у змінній оточення CONTENT_LENGTH, а тип даних - у змінній CONTENT_TYPE.

Передати дані методом POST можна тільки за допомогою HTML-форми, оскільки дані передаються в тілі запиту, а не в заголовку, як у GET. Відповідно і змінити значення параметрів можна, тільки змінивши значення, введене в форму. При використанні POST користувач не бачить чи передаються серверу дані.

Основна перевага POST запитів - це їхня велика безпека і функціональність у порівнянні з GET-запитами. Тому метод POST частіше використовують для передачі важливої інформації, а також інформації великого обсягу. Тим не менш не варто цілком покладатися на безпеку цього механізму, оскільки дані POST запиту також можна підробити, наприклад створивши html-файл на своїй машині і заповнивши його потрібними даними. Крім того, не всі клієнти можуть застосовувати метод POST, що обмежує варіанти його використання.

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

  • REMOTE_ADDR - IP-адреса хоста (комп'ютера), що відправляє запит;
  • REMOTE_HOST - ім'я хоста, з якого надіслано запит;
  • HTTP_REFERER - адреса сторінки, що посилається на поточний скрипт;
  • REQUEST_METHOD - метод, який був використаний при відправці запиту;
  • QUERY_STRING - інформація, яка перебуває в URL після знака питання;
  • SCRIPT_NAME - віртуальний шлях до програми, яка повинна виконуватися;
  • HTTP_USER_AGENT - інформація про браузер, який використовує клієнт

Обробка запитів за допомогою PHP

До цих пір ми згадували тільки, що запити клієнта обробляються на сервері за допомогою спеціальної програми. Насправді цю програму ми можемо написати самі, в тому числі і на мові PHP, і вона буде робити з отриманими даними все, що ми захочемо. Для того, щоб написати цю програму, необхідно познайомитися з деякими правилами і інструментами, запропонованими для цих цілей PHP.

Усередині PHP-скрипта є декілька способів отримання доступу до даних, переданим клієнтом по протоколу HTTP. До версії PHP 4.1.0 доступ до таких даних здійснювався за іменами переданих змінних (нагадаємо, що дані передаються у вигляді пар «ім'я змінної, символ« = », значення змінної»). Таким чином, якщо, наприклад, було передано first_name = Nina, то всередині скрипта з'являлася змінна $first_name зі значенням Nina. Якщо потрібно розрізняти, яким методом були передані дані, то використовувалися асоціативні масиви $HTTP_POST_VARS і $HTTP_GET_VARS, ключами яких були імена переданих змінних, а значеннями - відповідно значення цих змінних. Таким чином, якщо пара first_name = Nina передана методом GET, то $ HTTP_GET_VARS ["first_name"] = "Nina".

Використовувати в програмі імена переданих змінних безпосередньо небезпечно. Тому було вирішено починаючи з PHP 4.1.0 задіяти для звернення до змінних, переданих за допомогою HTTP-запитів, спеціальний масив - $ _REQUEST. Цей масив містить дані, передані методами POST і GET, а також за допомогою HTTP cookies. Це Суперглобальний асоціативний масив, тобто його значення можна отримати в будь-якому місці програми, використовуючи як ключ ім'я відповідної змінної (елементу форми).

Приклад 2. Припустимо, ми створили форму для реєстрації учасників заочної школи програмування, як у наведеному вище прикладі. Тоді у файлі 1.php, що обробляє цю форму, можна написати наступне:

<? Php 
$str = "Здрастуйте, 
". $_REQUEST [" First_name "]." 
". $_REQUEST [" Last_name "]."! <br> "; 
$str .= "Ви обрали для вивчення курс по 
". $_REQUEST [" Kurs "]; 
echo $str; 
?>

Тоді, якщо в формі ми ввели ім'я «Вася», прізвище «Петров» і вибрали серед усіх курсів курс по PHP, на екрані браузера отримаємо таке повідомлення:

Здравствуйте, Вася Петров! 
Ви обрали для вивчення курс по PHP

Після введення масиву $_REQUEST масиви $HTTP_POST_VARS і $HTTP_GET_VARS для однорідності були перейменовані в $_POST і $_GET відповідно, але самі вони з вжитку не зникли з міркувань сумісності з попередніми версіями PHP. На відміну від своїх попередників, масиви $_POST і $_GET стали суперглобальними, тобто доступними безпосередньо і всередині функцій і методів.

Наведемо приклад використання цих масивів. Припустимо, нам потрібно обробити форму, що містить елементи введення з іменами first_name, last_name, kurs (наприклад, форму form.html, наведену вище). Дані були передані методом POST, і дані, передані іншими методами, ми обробляти не хочемо. Це можна зробити наступним чином:

<? Php 
$Str = "Здрастуйте, 
". $_POST [" First_name "]." 
". $_POST [" Last_name "]."! <br> "; 
$Str .= "Ви обрали для вивчення курс по". 
$_POST ["Kurs"]; 
echo $Str; 
?>

Тоді на екрані браузера, якщо ми ввели ім'я «Вася», прізвище «Петров» і вибрали серед усіх курсів курс по PHP, побачимо повідомлення, як у попередньому прикладі:

Здравствуйте, Вася Петров! 
Ви обрали для вивчення курс по PHP

Для того, щоб зберегти можливість обробки скриптів більш ранніх версій, ніж PHP 4.1.0, була введена директива register_globals, що дозволяє чи забороняє доступ до змінних безпосередньо за їхніми іменами. Якщо у файлі налаштувань PHP параметр register_globals = On, то до змінних, переданим сервера методами GET і POST, можна звертатися просто за їхніми іменами (тобто можна писати $first_name). Якщо ж register_globals = Off, то потрібно писати $_REQUEST ["first_name"] або $_POST ["first_name"], $_GET ["first_name"], $HTTP_POST_VARS ["first_name"], $HTTP_GET_VARS ["first_name"]. З точки зору безпеки цю директиву краще відключати (тобто register_globals = Off). При включеній директиві register_globals перераховані вище масиви також будуть містити дані, передані клієнтом.

Іноді виникає необхідність дізнатися значення якої-небудь змінної оточення, наприклад метод, що використовувався при передачі запиту або IP-адреса комп'ютера, що відправив запит. Отримати таку інформацію можна за допомогою функції getenv(). Вона повертає значення змінної оточення, ім'я якої передано їй як параметр.

<? 
getenv ('REQUEST_METHOD'); 
// Поверне використаний метод 
echo getenv ('REMOTE_ADDR'); 
// Виведе IP-адресу користувача, 
// Послав запит 
?>

Все, що записано в URL після знака запитання, можна отримати за допомогою команди

getenv ('QUERY_STRING');

Завдяки цьому можна методом GET передавати дані в якому-небудь іншому вигляді. Наприклад, вказувати тільки значення декількох параметрів через знак плюс, а в скрипті розбивати рядок запиту на частини або можна передавати значення лише одного параметра. У цьому випадку в масиві $_GET з'явиться порожній елемент з ключем, рівним цьому значенню (всього рядка запиту), причому символ «+», що зустрівся в рядку запиту, буде замінений на підкреслення «_».

Методом POST дані передаються тільки за допомогою форм, і користувач (клієнт) не бачить, які саме дані відправляються серверу. Щоб їх побачити, хакер повинен підмінити нашу форму на власну. Тоді сервер відправить результати обробки неправильної форми не туди, куди потрібно. Щоб цього уникнути, можна перевіряти адресу сторінки, з якої були надіслані дані. Це можна зробити знову ж за допомогою функції getenv ():

getenv ('HTTP_REFERER');

Приклад обробки запиту за допомогою PHP

Нагадаємо, в чому полягало завдання, і уточнимо його формулювання. Потрібно написати форму для реєстрації учасників заочної школи програмування і після реєстрації відправити учаснику повідомлення. Ми назвали це повідомлення універсальним листом, але воно буде трохи відрізнятися від того листа, який ми склали вище. Тут ми не будемо відправляти що-небудь по електронній пошті, щоб не уподібнюватися спамерам, а просто згенеруємо це повідомлення і виведемо його на екран браузера. Початковий варіант форми реєстрації ми вже наводили вище. Змінимо його таким чином, щоб кожен хто реєструється, міг вибрати скільки завгодно курсів для відвідування, і не будемо підтверджувати отримання реєстраційної форми.

<h2> Форма для реєстрації студентів </ h2> 
<form action="1.php" method=POST> 
Ім'я <br> <input type = text name = "first_name" 
value = "Ваше ім'я"> <br> 
Прізвище <br> <input type=text name="last_name"> <br> 
E-mail <br> <input type=text name="email"> <br> 
lt;p> Виберіть курс, який ви б хотіли відвідувати: lt;br> 
lt;input type=checkbox name='kurs[]' value='PHP'> PHP <br> 
lt;input type=checkbox name='kurs[]' value='Lisp'> Lisp <br> 
lt;input type=checkbox name='kurs[]' value='Perl'> Perl <br> 
lt;input type=checkbox name='kurs[]' value='Unix'> Unix <br> 
lt;P> Що ви хочете, щоб ми знали про вас? <BR> 
lt;textarea name="comment" cols=32 rows=5> </ textarea> 
lt;input type=submit value="Відправте"> 
lt;input type=reset value="Відмінити"> 
</ Form>

Тут все досить просто і зрозуміло. Єдине, що можна відзначити, - це спосіб передачі значень елемента checkbox. Коли ми пишемо в імені елемента kurs [], це означає, що перший зазначений елемент checkbox буде записаний в перший елемент масиву kurs, другий зазначений checkbox - у другий елемент масиву і т.д. Можна, звичайно, просто дати різні імена елементів checkbox, але це ускладнить обробку даних, якщо курсів буде багато.

Скрипт, який все це буде розбирати і обробляти, називається 1.php (форма посилається саме на цей файл, що записано в її атрибуті action). За замовчуванням використовується для передачі метод GET, але ми вказали POST. За отриманими даними від зареєстрованої людини, скрипт генерує відповідне повідомлення. Якщо людина вибрала якісь курси, то йому виводиться повідомлення про час їх проведення та про лекторів, які їх читають. Якщо людина нічого не вибрав, то виводиться повідомлення про наступні збори заочної школи програмістів (ЗШП).

<? 
// Створимо масиви відповідностей курс - час його 
// Проведення та викладач курсу
$times = array ("PHP" => "14.30", "Lisp" => "12.00", 
"Perl" => "15.00", "Unix" => "14.00"); 
$lectors = array ("PHP" => "Василь Васильович", 
"Lisp" => "Іван Іванович", "Perl" => "Петро Петрович", "Unix" => "Семен Семенович"); 
define ("SIGN", "З повагою, адміністрація"); 
// Визначаємо підпис листа як константу 
define ("MEETING_TIME", "18.00"); 
// Задаємо час зборів студентів 
$date = "12 травня"; // задаємо дату проведення лекцій 
// Починаємо складати текст повідомлення 
$str = "Здрастуйте, шановний". $_POST ["First_name"]. "". $_POST ["Last_name "]."!<br>"; 
$str .= "<br> Повідомляємо Вам, що"; 
$kurses = $_POST ["kurs"]; // збережемо в цій змінній 
// Список вибраних курсів 
if (!isset ($kurses)) {// якщо не обраний жоден курс 
$event = "наступні збори студентів"; 
$str .= "$event відбудеться $date". MEETING_TIME. "<br>"; 
} Else {// якщо хоча б один курс вибраний 
$event = "обрані Вами лекції відбудуться $date <ul>"; 
// Функція count обчислює число елементів у масиві 
$lect = ""; 
for ($i = 0; $i <count ( kurses); $i++) { 
// Для кожного обраного курсу 
$k = $kurses [$i]; // запам'ятовуємо назву курсу 
$lect = $lect. "<li> Лекція з $k в $times [$k]"; 
// Складаємо повідомлення 
$lect .= "(Ваш лектор, $lectors [$k])"; 

$event = $event. $lect. "</ Ul>"; 
$str .= "$event"; 

$str .= "<br>". SIGN; // додаємо підпис 
echo $str; // виводимо повідомлення на екран 
?>

Суперглобальні масиви

Розглянемо роботу суперглобальних змінних в PHP.

У PHP існує кілька суперглобальний змінних, а точніше суперглобальних масивів:

  • $_SERVER
  • $_GET
  • $_POST
  • $_FILES
  • $_COOKIE
  • $_SESSION
  • $_REQUEST
  • $_ENV

Суперглобальний масив $_SERVER

Масив являє собою інформацію про заголовки, шляхи та розміщення скриптів. Записи в цьому масиві створюються веб-сервером. Не існує гарантій, що веб-сервер сформує цей масив з усіма параметрами. Даний масив містить такі елементи:

PHP_SELF: ім'я файлу, що в даний час виконується PHP-скриптом. Наприклад при виконанні скрипта http://phpprogs.ru/test/guestbook2/ даний елемент буде приймати значення / test/guestbook2/index.php.

argv: список аргументів, переданих скрипту. Якщо використовує в командному рядку, то отримуєте масив значень, якщо використовується $_GET, то буде містити рядок запиту.

argc: містить число параметрів переданих сценарієм (якщо запуск був з командного рядка).

GATEWAY_INTERFACE: параметр повертає версію CGI, яку використовує веб-сервер.

SERVER_ADDR: елемент містить IP адресу сервера, де виконується скрипт.

SERVER_NAME: елемент містить ім'я веб-сервера, де виконується скрипт.

SERVER_SOFTWARE: ідентифікаційний рядок веб-сервера, який повертається у відповідь при запитах.

SERVER_PROTOCOL: ім'я та версія протоколу HTTP.

REQUEST_METHOD: використовуваний метод запиту до веб-сервера (POST, GET, HEAD, PUT).

REQUEST_TIME: відмітка про час початку запиту (починаючи з PHP 5.1.0).

QUERY_STRING: рядок запиту до веб-сторінки, якщо вона існує, за допомогою якого був здійснений доступ до сторінки

DOCUMENT_ROOT: коренева директорія, з якої виконується скрипт.

HTTP_ACCEPT: зміст заголовка ACCEPT, якщо він є.

HTTP_ACCEPT_CHARSET: зміст заголовка ACCEPT-CHARSET, якщо він є. Наприклад 'iso-8859-1, *, utf-8'.

HTTP_ACCEPT_ENCODING: зміст заголовка ACCEPT-ENCODING, якщо він є. Наприклад 'gzip'.

HTTP_ACCEPT_LANGUAGE: зміст заголовка ACCEPT-LANGUAGE, якщо він є. Наприклад 'en'.

HTTP_ACCEPT_CONNECTION: зміст заголовка ACCEPT-CONNECTION, якщо він є. Наприклад 'Keep-Alive'.

HTTP_HOST: зміст заголовка HOST, тобто він є.

HTTP_REFERER: адреса сторінки, з якої на поточну сторінку перейшло програмне забезпечення користувача. Не всі ПЗ користувача передають цей параметр, а деякиі ПЗ навіть змінюють його. Отже, даному параметру довіряти не можна.

HTTP_USER_AGENT: цей параметр містить інформацію про клієнт користувача (ПО користувача), який звертається до сторінки. Наприклад 'Mozilla/4.5 [RU] (X11; U; Linux 2.2.9 i586). Також цю інформацію Ви можете отримати з функції get_browser ().

HTTPS: параметр містить інформацію, якщо запит був зроблений через HTTPS.

REMOTE_ADDR: IP-адреса користувача, з якого він переглядає сторінку.

REMOTE_HOST: ім'я хоста користувача, з якого він переглядає цю сторінку.

REMOTE_POST: порт, який використовується для з'єднання з веб-сервером.

SCRIPT_FILENAME: абсолютний шлях до поточного скрипта.

SERVER_ADMIN: значення SERVER_ADMIN, взяте з конфігураційного файлу Apache.

SERVER_PORT: порт веб-сервера, використаний для передачі даних по HTTP. За замовчуванням 80.

SERVER_SIGNATURE: рядок, що містить версію веб-сервера і ім'я віртуального хоста.

PATH_TRANSLATED: базовий шлях до поточного сценарія.

SCRIPT_NAME: містить шлях та ім'я поточного скрипта.

REQUEST_URI: URI для поточної сторінки.

PHP_AUTH_DIGEST: якщо PHP працює як модуль Apache, то параметр використовується як реквізити по протоколу HTTP для перевірки автентичності.

PHP_AUTH_USER: якщо PHP працює як модуль Apache або IIS, то параметр містить ім'я користувача при аутентифікації по протоколу HTTP.

PHP_AUTH_PW: якщо PHP працює як модуль Apache або IIS, то параметр містить пароль користувача при аутентифікації по протоколу HTTP.

AUTH_TYPE: якщо PHP працює як модуль Apache або IIS, то параметр містить тип аутентифікації по протоколу HTTP.

Суперглобальний масив $_GET

Масив $_GET представляє собою асоціативний масив елементів, переданих за допомогою HTTP GET запитів поточному PHP-скрипту. Немає необхідності оголошувати масив $_GET всередині функції користувача командою "global $_GET;", тому що даний масив є суперглобальний.

Суперглобальний масив $_POST

Масив $_POST представляє собою асоціативний масив елементів, переданих за допомогою HTTP POST запитів поточному PHP-скрипту. Немає необхідності оголошувати масив $_POST всередині функції користувача командою "global $_POST;", тому що даний масив є суперглобальний.

Суперглобальний масив $_FILES

Масив $_FILES представляє собою асоціативний масив елементів, переданих за допомогою HTTP POST запитів поточному PHP-скрипту. Немає необхідності оголошувати масив $_FILES всередині функції користувача командою "global $_FILES;", тому що даний масив є суперглобальний.

Суперглобальний масив $_COOKIE

Масив $_COOKIE представляє собою асоціативний масив елементів, переданих за допомогою HTTP COOKIE запитів поточному PHP-скрипту. Немає необхідності оголошувати масив $_COOKIE всередині функції користувача командою "global $_COOKIE;", тому що даний масив є суперглобальний.

Суперглобальний масив $_SESSION

Даний асоціативний масив містить змінні сесії, доступні для даного скрипта. Немає необхідності оголошувати масив $_SESSION всередині функції користувача командою "global $_SESSION;", тому що даний масив є суперглобальний.

Суперглобальний масив $ _REQUEST

Масив $_REQUEST є об'єднаним асоціативним масивом, який включає в себе масиви $_GET, $_POST, $_FILES. Немає необхідності оголошувати масив $_REQUEST всередині функції користувача командою "global $_REQUEST;", тому що даний масив є суперглобальний.

Суперглобальний масив $ _ENV

$_ENV Представляє собою асоціативний масив, який містить значення змінних з середовища, в якій працює інтерпретатор PHP. Немає необхідності оголошувати масив $_ENV всередині функції користувача командою "global $_ENV;", тому що даний масив є суперглобальний.

PHP і Cookies

Cookies - це механізм зберігання даних броузером віддаленого комп'ютера для ідентифікації відвідувачів і зберігання параметрів веб-сторінок (наприклад, змінних).

Наведемо приклад використання Cookies на конкретному прикладі.

Припустимо, нам потрібно написати лічильник відвідування сайту. Нам потрібно знати, яке число відвідувань сайту здійснювалося кожним конкретним користувачем.

Дану задачу можна вирішити двома способами. Перший з них полягає у веденні обліку IP-адрес користувачів. Для цього потрібна база даних всього з однієї таблиці, приблизна структура якої така:

IP-адреса                  Число відвідувань 
210.124.134.203       7 
212.201.78.207         14 
83.103.203.73           3

Коли користувач заходить на сайт, нам потрібно визначити його IP-адресу, знайти в базі даних інформацію про його відвідини, збільшити лічильник і вивести його в браузер відвідувача. Написати обробник (скрипт) подібної процедури нескладно. Проте при використанні такого методу у нас з'являються проблеми наступного характеру:

  • Для кожногї IP-адреси потрібно вести облік в одній таблиці, яка може бути дуже великою. А з цього випливає, що ми нераціонально використовуємо процесорний час і дисковий простір;
  • У більшості домашніх користувачів IP-адреси є динамічними. Тобто, сьогодні у нього адреса 212.218.78.124, а завтра - 212.218.78.137. Таким чином, велика вірогідність ідентифікувати одного користувача кілька разів.

Можна використовувати другий спосіб, який набагато легший в реалізації і є більш ефективним. Ми встановлюємо в Cookie змінну, яка буде зберігатися на диску віддаленого користувача. Ця змінна буде зберігати інформацію про відвідування. Вона буде зчитуватися скриптом при зверненні користувача до сервера. Вигода такого методу ідентифікації очевидна. По-перше, нам не потрібно зберігати безліч непотрібної інформації про IP-адреси. По-друге, нас не цікавлять динамічні IP-адреси, оскільки дані про відвідання зберігаються конкретно у кожного відвідувача сайту.

Тепер зрозуміло, для чого ми можемо використовувати Cookie - для зберігання невеликої за обсягом інформації у клієнта (відвідувача) сайту, наприклад: налаштування сайту (колір фону сторінок, мова, оформлення таблиць і.т.д.), а також іншої інформації.

Файли Cookies представляють собою звичайні текстові файли, які зберігаються на диску у відвідувачів сайтів. Файли Cookies і містять ту інформацію, яка була в них записана сервером.

Програмування Cookies

Приступимо до програмування Cookies.

Для установки Cookies використовується функція SetCookie (). Для цієї функції можна вказати шість параметрів, один з яких є обов'язковим:

  • name - задає ім'я (рядків), закріплене за Cookie;
  • value - визначає значення змінної (рядок);
  • expire - час "життя" змінної (ціле число). Якщо цей параметр не вказувати, то Cookie будуть "жити" до кінця сесії, тобто до закриття браузера. Якщо час вказано, то, коли він настане, Cookie самознищиться.
  • path - шлях до Cookie (рядок);
  • domain - домен (рядок). Як значення встановлюється ім'я хоста, з якого Cookie був записаний;
  • secure - передача Cookie через захищене HTTPS-з'єднання.

Зазвичай використовуються тільки три перші параметра.

Приклад установки Cookies: 
<? Php 

// Встановлюємо Cookie до кінця сесії: 
SetCookie ("Test", "Value"); 

// Встановлюємо Cookie на одну годину після установки: 
SetCookie ("My_Cookie", "Value", time () +3600); 

?>

При використанні Cookies необхідно мати на увазі, що Cookies повинні встановлюватися до першого виводу інформації в браузер (наприклад, оператором echo або якої-небудь іншої функції). Тому бажано встановлювати Cookies на самому початку скрипта. Cookies встановлюються за допомогою певного заголовка сервера, а якщо скрипт виводить що-небудь, то це означає, що починається тіло документа. У результаті Cookies не будуть встановлені і може бути виведено попередження. Для перевірки успішності установки Cookies можна використовувати такий метод:

<? Php 
// Встановлюємо Cookie до кінця сесії: 
// В разі успішного встановлення Cookie, функція SetCookie повертає TRUE: 
if (SetCookie ("Test", "Value")) echo "<h3> Cookies успішно встановлені! </ h3>"; 
?>

Функція SetCookie () повертає TRUE у випадку успішної установки Cookie. У випадку, якщо Cookie встановити не вдається SetCookie () поверне FALSE і можливо, попередження (залежить від налаштувань PHP). Приклад невдалого встановлення Cookie:

<? Php 
// Cookies встановити не вдасться, оскільки перед відправкою 
// Заголовка Cookie ми виводимо в браузер рядок 'Hello': 
echo "Hello"; 
// Функція SetCookie поверне FALSE: 
if (SetCookie ("Test", "Value")) echo "<h3> Cookie успішно встановлено! </ h3>"; 
else echo "<h3> Cookie встановити не вдалося! </ h3>"; 
// Виводить 'Cookie встановити не вдалося!'. 
?>

Cookie встановити не вдалося, оскільки перед посилкою заголовка Cookie ми вивели в браузер рядок "Hello".

Читання значень Cookies

Отримати доступ до Cookies та їх значенням досить просто. Вони зберігаються в суперглобальних масивах і $_COOKIE і $HTTP_COOKIE_VARS.

Доступ до значень здійснюється за ім'ям встановлених Cookies, наприклад:

echo $_COOKIE ['my_cookie']; 
// Виводить значення встановленої Cookie 'My_Cookie' 
Приклад встановлення Cookie і подальшого його читання: 
<? Php 
// Встановлюємо Cookie 'test' зі значенням 'Hello' на одну годину: 
setcookie ("test", "Hello", time () +3600); 
// При наступному запиті скрипта виводить 'Hello': 
echo @$ _COOKIE ['test']; ?>

У розглянутому прикладі при першому зверненні до скрипта встановлюється Cookie "test" із значенням "hello". При повторному зверненні до скрипта буде виведено значення Cookie "test", тобто рядок "Hello".

При читанні значень Cookies звертайте увагу на перевірку існування Cookies, наприклад, використовуючи оператор isset (). Або шляхом заборони виводу помилок оператором @

А ось приклад, як побудувати лічильник числа завантажень сторінки за допомогою Cookies:

<? Php 
// Перевіряємо, чи був вже встановлений Cookie 'Mortal', 
// Якщо так, то читаємо його значення, 
// І збільшуємо значення лічильника звернень до сторінки: 
if (isset ($ _COOKIE ['Mortal'])) $cnt = $_COOKIE ['Mortal'] +1; 
else $ cnt = 0; 
// Встановлюємо Cookie 'Mortal' із значенням лічильника, 
// З часом "життя" до 18/07/29, 
// Тобто на дуже довгий час: 
setcookie ("Mortal", $ cnt, 0x6FFFFFFF); 
// Виводить число відвідувань (завантажень) цієї сторінки: 
echo "<p> Ви відвідували цю сторінку <b> ".@$_ COOKIE ['Mortal']."</ b> раз </ p>"; 
?>

Видалення Cookies

Іноді виникає необхідність видалення Cookies. Зробити це нескладно, необхідно лише знову встановити Cookie з ідентичним ім'ям і порожнім параметром. Наприклад:

<? Php 
// Видаляємо Cookie 'Test': 
SetCookie ("Test ",""); 
?>

Створення масиву Cookies і його читання

Ми можемо створити масив Cookies, а потім прочитати масив Cookies та значення цього масиву:

<? Php 
// Передаємо масив Cookies: 
setcookie ("cookie [1]", "Перший"); 
setcookie ("cookie [2]", "Другий"); 
setcookie ("cookie [3]", "Третій"); 

// Після перезавантаження сторінки ми відобразимо 
// Вміст масиву Cookies 'cookie': 
if (isset ($_COOKIE ['cookie'])) { 
foreach ($_COOKIE ['cookie'] as $name => $value) { 
echo "$ name: $ value <br>"; 


?>

Переваги використання Cookies незаперечні. Проте існують і деякі проблеми їх використання. Перша з них полягає в тому, що відвідувач може блокувати Cookies браузером або просто видалити всі Cookies або їх частину. Таким чином, ми можемо мати деякі проблеми в ідентифікації таких відвідувачів.

Робота з сесією

Етапи роботи з сесіями

  1. Установка імені сесії (не обов'язково).
  2. Створення сесії.
  3. Реєстрація змінних сесії і їх використання.
  4. Видалення змінних сесії.
  5. Знищення сесії.

Створення сесії

Перше, що потрібно зробити для роботи з сесіями (якщо вони вже налаштовані адміністратором сервера), це запустити механізм сесій. Якщо в налаштуваннях сервера змінна session.auto_start встановлена в значення "0" (якщо session.auto_start = 1, то сесії запускаються автоматично), то будь-який скрипт, в якому потрібно використовувати дані сесії, повинен починатися з команди

session_start ();

Отримавши таку команду, сервер створює нову сесію або відновлює поточну, ґрунтуючись на ідентифікаторі сесії, переданому запитом. Як це робиться? Інтерпретатор PHP шукає змінну, в якій зберігається ідентифікатор сесії (за умовчанням це PHPSESSID) спочатку в cookies, потім в змінних, переданих за допомогою POST-і GET-запитів. Якщо ідентифікатор знайдений, то користувач вважається ідентифікованим, проводиться заміна всіх URL і виставлення cookies. В іншому випадку користувач вважається новим, для нього генерується новий унікальний ідентифікатор, потім проводиться заміна URL і виставлення cookies.

Команду session_start () потрібно викликати у всіх скриптах, у яких доведеться використовувати змінні сесії, причому до виведення яких-небудь даних в браузер. Це пов'язано з тим, що cookies виставляються тільки до виведення інформації на екран.

Отримати ідентифікатор поточної сесії можна за допомогою функції session_id ().

Для наочності сесії можна задати ім'я за допомогою функції session_name ([імя_сессії]). Робити це потрібно ще до ініціалізації сесії. Отримати ім'я поточної сесії можна за допомогою цієї ж функції, викликаної без параметрів: session_name ();

Ім'я сесії - це ім'я параметра, в якому зберігається ідентифікатор сесії.

Приклад створення сесії;

<? 
session_start (); 
// Створюємо нову сесію або 
// Відновлюємо поточну 
echo session_id (); 
// Виводимо ідентифікатор сесії 
?> 
<html> 
<head> <title> My home page </ title> </ head> 
... // Домашня сторінка 
</ Html> 
<? 
echo session_name (); 
// Виводимо ім'я поточної сесії. 
// У даному випадку це PHPSESSID 
?>

Якщо ж створити файл authorize.php, то значення змінних, що виводяться (id сесії та її ім'я) будуть такими ж, якщо перейти на нього з index.php і не закривати перед цим вікно браузера, тоді ідентифікатор сесії зміниться.

Реєстрація змінних сесії

Однак від самого ідентифікатора та імені сесії нам користі для вирішення наших завдань небагато. Ми ж хочемо передавати і зберігати протягом сесії наші власні змінні (наприклад, логін і пароль). Для того щоб цього досягти, потрібно просто зареєструвати свої змінні:

session_register (ім’я_змінної1, 
ім’я_змінної2, ...);

Увага! session_register є застарілою і у версії PHP 6.0 взагалі вилучена. Її використання вкрай не бажано. Замість session_register слід використовувати $_SESSION.

Зауважимо, що реєструються не значення, а імена змінних. Зареєструвати змінну достатньо один раз на будь-якій сторінці, де використовуються сесії. Імена змінних передаються функції session_register () без знаку $. Усі зареєстровані таким чином змінні стають глобальними (тобто доступними з будь-якої сторінки) протягом даної сесії роботи з сайтом.

Зареєструвати змінну також можна, просто записавши її значення в асоціативний масив $ _SESSION, тобто написавши

$_SESSION ['Ім'я_змінної'] = 
'Значення_змінної';

У цьому масиві зберігаються всі зареєстровані (тобто глобальні) змінні сесії.

Доступ до таких змінних здійснюється за допомогою масиву $_SESSION ['ім'я_змінної'] (або $HTTP_SESSION_VARS ['ім'я_змінної'] для версії PHP 4.0.6 і більш ранніх). Якщо ж в налаштуваннях php включена опція register_globals, то до сесійних змінних можна звертатися ще й як до звичайних змінних, наприклад так: $ім'я_змінної.

Якщо register_globals = off (відключені), то користуватися session_register () для реєстрації змінних переданих методами POST або GET, не можна, тобто це просто не працює. І взагалі, не рекомендується одночасно використовувати обидва методи реєстрації змінних, $_SESSION і session_register ().

Приклад реєстрація змінних

Зареєструємо логін і пароль, які вводяться користувачем на сторінці авторизації.

<? 
session_start (); 
// Створюємо нову сесію або 
// Відновлюємо поточну 
if (! isset ($_GET ['go'])){ 
echo "<form> 
Login: <input type=text name=login> 
Password: <input type = password 
name = passwd> 
<input type=submit name=go value=Go> 
</ Form> "; 
} Else { 
$_SESSION ['Login']=$_ GET [' login ']; 
// Реєструємо змінну login 
$_SESSION ['Passwd']=$_ GET [' passwd ']; 
// Реєструємо змінну passwd 
// Тепер логін і пароль - глобальні 
// Змінні для цієї сесії 
if ($_GET ['login']==" pit "&& 
$_GET ['Passwd']==" 123 ") { 
Header ("Location: secret_info.php"); 
// Перенаправляємо на сторінку 
// Secret_info.php 
} Else echo "Невірний введення, 
спробуйте ще раз <br> "; 

print_r ($_SESSION); 
// Виводимо всі змінні сесії 
?>

Вміст файлу authorize.php

Тепер, потрапивши на сторінку secret_info.php, та й на будь-яку іншу сторінку сайту, ми зможемо працювати з введеними користувачем логіном і паролем, які будуть зберігатися в масиві $ _SESSION. Таким чином, якщо змінити код секретної сторінки (зауважте, ми перейменували її в secret_info.php) так:

<? Php 
session_start (); 
// Створюємо нову сесію або 
// Відновлюємо поточну 
print_r ($ _SESSION); 
// Виводимо всі змінні сесії 
?> 
<html> 
<head> <title> Secret info </ title> </ head> 
<body> 
<p> Тут я хочу ділитися секретами 
з одним Петром. 
</ Body> 
</ Html>

Вміст файлу secret_info.php

То ми отримаємо в браузері на секретній сторінці наступне:

Array ([login] => pit [passwd] => 123) 
Тут я хочу ділитися секретами 
з одним Петром.

У результаті отримаємо список змінних, зареєстрованих на authorize.php і, власне, саму секретну сторінку.

Що це нам дає? Припустимо, хакер хоче прочитати секрети Васі і Петі. І він якось дізнався, як називається секретна сторінка (або сторінки). Тоді він може спробувати просто ввести її адресу в рядку браузера, минаючи сторінку авторизації (введення пароля). Щоб уникнути такого проникнення в наші таємниці, потрібно дописати всього пару рядків у код секретних сторінок:

<? Php 
session_start (); 
// Створюємо нову сесію або 
// Відновлюємо поточну 
print_r ($ _SESSION); 
// Виводимо всі змінні сесії 
if (!($_ SESSION ['login'] == pit && 
$ _SESSION ['Passwd'] == 123)) 
// Перевіряємо правильність 
// Пароля-логіна 
Header ("Location: authorize.php"); 
// Якщо помилка, то перенаправляємо на 
// Сторінку авторизації 
?> 
<html> 
<head> <title> Secret info </ title> </ head> 
... / / Тут розташовується 
/ / Секретна інформація:) 
</ Html>

Код 2-ї версіі secret_info.php

Видалення змінних сесії

Крім наіичок реєстрації змінних сесії (тобто робити їх глобальними протягом всього сеансу роботи), корисно також вміти видаляти такі змінні і сесію в цілому.

Функція session_unregister (ім'я_змінної) видаляє глобальну змінну з поточної сесії (тобто видаляє її з списку зареєстрованих змінних). Якщо реєстрація проводилася за допомогою $_SESSION ($HTTP_SESSION_VARS для версії PHP 4.0.6 і більш ранніх), то використовують мовну конструкцію unset (). Вона не повертає ніякого значення, а просто знищує зазначені змінні.

Увага! session_unregister застаріла! Слід використовувати unset ($_SESSION ['ім'я змінної']);

Де це може стати в нагоді? Наприклад, для знищення даних про відвідувача (зокрема, логіна і пароля) після його виходу з секретної сторінки. Якщо правильні логін і пароль збережуться і вікно браузера після відвідування сайту не закрили, то будь-який інший користувач цього комп'ютера зможе прочитати закриту інформацію.

Приклад знищення змінних сесії

У файл secret_info.php додамо рядок для виходу на головну сторінку:

<? Php 
// ... php код 
?> 
<html> 
<head> <title> Secret info </ title> </ head> 
... // Тут розташовується 
// Секретна інформація:) 
<a href="index.php"> На головну </ a> 
</ Html>

У Index.php знищимо логін і пароль, введені раніше:

Вміст файлу index.php

<? 
session_start (); 
session_unregister ('passwd'); 
// Знищуємо пароль 
unset ($ _SESSION ['login']); 
// Знищуємо логін 
print_r ($ _SESSION); 
// Виводимо глобальні змінні сесії 
?> 
<html> 
<head> <title> My home page </ title> / head> 
....// Домашня сторінка 
</ Html>

Тепер, щоб потрапити на секретну сторінку, потрібно буде знову вводити логін і пароль.

Для того щоб скинути значення всіх змінних сесії, можна використовувати функцію session_unset ();

Знищити поточну сесію цілком можна командою session_destroy (); Вона не скидає значення глобальних змінних сесії і не видаляє cookies, а знищує всі дані, асоційовані з поточною сесією.

Приклад знищення сесії і глобальних змінних

<? 
session_start (); // ініціюємо сесію 
$test = "Змінна сесії"; 
$_SESSION ['Test'] = $test; 
// Реєструємо змінну $test. 
// Якщо register_globals = on, 
// То можна використовувати 
// Session_register ('test'); 

print_r ($ _SESSION); 
// Виводимо всі глобальні змінні 

echo session_id (); 
// Виводимо ідентифікатор сесії 

echo "<hr>"; 
session_unset (); 
// Знищуємо всі глобальні 
// Змінні сесії 
print_r ($_SESSION); 
echo session_id (); 
echo "<hr>"; 
session_destroy (); // знищуємо сесію 
print_r ($ _SESSION); 
echo session_id (); 
?>

У результаті роботи цього скрипта будуть виведені три рядки: у першому - масив з елементом test і його значенням, а також ідентифікатор сесії, у другому - порожній масив і ідентифікатор сесії, в третьому - порожній масив. Таким чином, видно, що після знищення сесії знищується і її ідентифікатор, і ми більше не можемо ні реєструвати змінні, ні взагалі проводити які-небудь дії з сесією.