Работа с сессиями в PHP. Простая авторизация

Работа с сессиями
Простая авторизация



Открытие сессии

Запись и получение данных из сессии

Удаление данных из сессии

Простая авторизация

Избавление от проблемы F5

Механизм выхода из сессии



$_SESSION - ассоциативный массив, содержащий переменные сессии, которые доступны для текущего скрипта. Это суперглобальная переменная , она доступна во всех контекстах скрипта.

Сессия - очень полезная возможность, которая позволяет, в том числе, передавать данные между страницами.

Это значит, коль $_SESSION - глобальный массив, то если мы запишем в него какие-то данные на одной странице, то эти данные будут доступны на другой странице на протяжении всей сессии (на протяжении всего сеанса), чего нет с любыми другими массивами. Конец сессии или сеанса - это закрытие браузера .

Для работы с сессиями существуют специальные функции: php.net


Наиболее полезные функции для работы с сессиями


session_start - открывает сессию, либо возобновляет ее, если файл сессии был найден.
session_unset - она удаляет все переменные текущей сессии.
session_destroy - уничтожает все данные, связанные с текущей сессией. Данная функция не удаляет какие-либо глобальные переменные, связанные с сессией и не удаляет сессионные cookie.
session_id - эта функция используется для получения или установки идентификатора текущей сессии.
session_name - возвращает имя текущей сессии. Если задан параметр name, session_name() обновит имя сессии и вернет старое имя сессии.



Открытие сессии




session_start - это та функция, которую мы должны выполнить, перед тем, как работать с сессиями. Данная функция запускает или открывает сессию и по сути, поскольку нам необходимо хранить данные, которые будут доступны между страницами, то сессия - это ничто иное как файл, который хранится во временной папке (эта папка будет хранится в папке: userdata/temp для Open Server) В этот текстовый файл записываются все те данные, которые мы сохраняем в сессию. И когда мы запускаем на выполнение функцию session_start, то она создает такой файл либо обращается к нему, если файл уже был создан ранее. Причем этот файл индивидуален для каждой открытой сессии. Это значит, что если мы обратимся к одному и тому же скрипту из двух различных браузеров, то под каждый браузер, под каждого клиента будет открыт свой файл сессии и эти файлы никак друг с другом не пересекаются. Из этого следует, что с помощью сессий, мы можем организовать механизм аторизации пользователя, то есть получения доступа к какой-то закрытой части сайта.

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

Куки - это тот же самый файл, который хранится не на сервере, а на стороне клиента (в браузере), в нем содержится индификатор , который совпадает с идификатором файла , который лежит на сервере.



Запись и получение данных из сессии




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

Для примера создадим три файла: sess1.php, sess2.php и secret.php


В файле sess1.php запишем в массив $_SESSION имя Андрей . При обновлении страницы в браузере это имя - выведится.

Функция session_start чувствительна к выводу - перед вызовом данной функции не должно быть никакого вывода в браузер . Если поставить перенос строки, который является выводом в браузер, то возникнет ошибка.


Файл sess1.php


-- файл sess1.php --

// здесь ничего не должно быть
<?php
session_start(); // открываем сессию

echo session_id(); // индификатор сессии, который равен значению куки

$_SESSION ['name']= 'Андрей'; // запишем в массив имя
echo $_SESSION['name']; // выводим $_SESSION['name']

// выведет: Андрей
// в файле сессии будет записано: name|s:12:"Андрей";
?>



После обновлении страницы получим:


sess1.png



В файле сессии будет сделана запись: name|s:12:"Андрей" - сериализованная строка - это один из способов хранения массивов данных, где:
- name - ключ
- s:12 - длина строки в байтах (в кодировке utf-8, буквы кирилицы равны двум байтам)
- Андрей - содержимое $_SESSION['name']
Если закомментировать строку $_SESSION['name']= 'Андрей' , то в браузере, при обнавлении все равно выведится имя Андрей, это значит, что в сессии эти данные были запомненны . В этом можно убедиться, открыв файл сессии.


В файле sess2.php откраваем сессию и получаем доступ, к тому, что лежит в сессии - к тому же $_SESSION['name'].


Файл sess2.php


-- файл sess2.php --

<?php
session_start(); // открываем сессию
echo $_SESSION['name']; // выводим $_SESSION['name']
// выведет: Андрей
?>




Удаление данных из сессии




Если мы хотим удалить из сессии конкретное значени можно использовать функцию unset(), которая удаляет переменную - в данном случае нам надо удалить - $_SESSION['name']. И удалив его, на какой то странице (на sess1.php), мы удаляем его целиком из сессии.

Если нам нужно удалить все значения сессии , то есть все переменные массива , можно использовать специальную функцию session_unset() которая удалит все сессионные переменные. Сессионый файл будет очищен.

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


Файл sess1.php


-- файл sess1.php --

<?php
session_start(); // открываем сессию

$_SESSION['name']= 'Андрей' ; // запишем в массив имя
$_SESSION['login']= 'andrey' ; // запишем в массив логин
echo $_SESSION['name']; // выводим $_SESSION['name']

// выведет: Андрей
// в файле сессии будет записано: name|s:12:"Андрей";

unset($_SESSION['name']); // удаляем из сессии конкретное значение
session_unset(); // удаляет из сессии все переменные
session_destroy(); // уничтожает сессию, включая и сам сессионный файл
?>




Простая авторизация




Создадим пункты меню и поместим их в каждый из файлов: sess1.php , sess2.php и secret.php . Наша задача - ограничить доступ к странице secret.


<ul>
<li><a href="sess1.php"> sess1 </a></li>
<li><a href="sess2.php"> sess2 </a></li>
<li><a href="secret.php"> secret </a></li>
</ul>



Что бы ограничить доступ к странице secret.php мы задаем простое условие (авторизация будет происходить по логину):

Если у нас не существует (!isset ) в сессии ($_SESSION) элемент ( admin ) - мы завершим работу и выведем:"Вы не авторизованы!",

( die или exit - вывести сообщение и прекратить выполнение текущего скрипта)

если мы прошли проверку, то выведем: "Добро пожаловать, {$_SESSION['admin']}"


Файл secret.php


-- файл secret.php --

<?php
session_start(); // открываем сессию

if ( ! isset ($_SESSION[ 'admin' ])) die( 'Вы не авторизованы!');
echo "Добро пожаловать, {$_SESSION[ 'admin' ]}";
?>

<ul>
<li><a href="sess1.php"> sess1 </a></li>
<li><a href="sess2.php"> sess2 </a></li>
<li><a href="secret.php"> secret </a></li>
</ul>



На странице файл sess1.php создадим форму авторизации:
- action="" - обработчик будет на этой же странице
- method="post" - метод POST
- input type="text" - поле ввода
- name="login" - имя "login"
- type="submit" - кнопка тип "submit"
- Login - надпись


Далее нам необходимо принять данные из формы: если не пуст (!empty) элемент с ключем login ($_POST['login']), то мы должны сравнить, то что передал пользователь с каким-то нашим логином - с тем логином, который мы разрешаем для авторизации. Его определим в виде константы: имя константы - ADMIN, значение - строка admin - такой логин будет разрешен.

Далее проверяем: если у нас $_POST['login'] будет равен значению константы ADMIN, мы должны записать что-то в сессию, а именно создать сессионную переменную $_SESSION['admin'] = ADMIN, и выведем сообщение: "Вы успешно авторизовались!".

В противном случае выведем: "Неверный логин" .


Файл sess1.php


-- файл sess1.php --

<?php
// определяем константу для сравнения с логином пользователя
define('ADMIN' , 'admin' );

// открываем сессию
session_start();

// принимаем данные из формы
if(!empty( $_POST['login'])){
// создаем сессионную переменную
if( $_POST['login'] === ADMIN ){
$_SESSION[ 'admin' ] = ADMIN ;
echo 'Вы успешно авторизовались!';
} else{
echo 'Неверный логин' ;
}
}
?>

<ul>
<li><a href="sess1.php"> sess1 </a></li>
<li><a href="sess2.php"> sess2 </a> </li>
<li><a href="secret.php"> secret </a></li>
</ul>

<hr>

<!-- форма авторизации -->
<form action="" method="post">
<input type="text" name="login">
<button type="submit"> Login </button>
</form>




Избавление от проблемы F5




При обновлении страницы возникает проблема F5.

Чтобы избавиться от этой проблемы нам надо перезапросить страницу. Чтобы перезапросить страницу средствами PHP, мы можем сделать редирект: header("location: sess1.php"). И для того, чтобы дальше ничего не выполнялось, мы должны завершить выполнение скрипта: die, а чтобы получить сообщение о регистрации его надо записать в сессию : $_SESSION['res'] = 'Вы успешно авторизовались!' и вывести: если у нас существует (if(isset)) в сессии $_SESSION элемент ['res'], то выведем его echo $_SESSION['res'].

То же самое мы можем сделать и для ошибки: $_SESSION['res'] = 'Неверный логин' , И редирект теперь нужен для любого случая, и в случае ошибки, и в случае успеха. Вынесем его за пределы условий.

Удалим ненужную переменную из сессии: unset($_SESSION['res']).

Окончательно запишем:


Файл sess1.php


-- файл sess1.php --

<?php
// открываем сессию
session_start();

// определяем константу для сравнения с логином пользователя
define('ADMIN', 'admin' );

// принимаем данные из формы
// если у нас что-то пришло POST-ом
if ( ! empty( $_POST['login'])){
// и если это равно константе ADMIN
if( $_POST['login'] === ADMIN ){
// тогда мы создадим сессионную переменную,
// чтобы мы могли попасть на страницу secret
$_SESSION [ 'admin' ] = ADMIN ;

// записываем сообщение в сессию об успехе
$_SESSION [ 'res' ] = 'Вы успешно авторизовались!' ;

} else{
// иначе запишем сообщение об ошибке
$_SESSION [ 'res' ] = 'Неверный логин' ;
}
// и сделаем в любом случае редирект,
// чтобы перезапросить страницу и сбросить данные из формы
header( "Location: sess1.php");
// и завершаем выполнение скрипта
die;
}
?>
<ul>
<li>< a href="sess1.php" > sess1 </a></li>
<li>< a href="sess2.php" > sess2 </a></li>
< li>< a href="secret.php" > secret </a></li>
</ul>
<hr>
<!-- если существует сессионная переменная, то выводим сообщение -->
<?php
if ( isset ( $_SESSION [ 'res' ])){
echo $_SESSION [ 'res' ];
// удалим ненужную переменную из сессии
//(после обновления страницы сообщение - не нужно)
unset( $_SESSION [ 'res' ]);
}
?>
<!-- форма авторизации -->
<form action="" method="post">
<input type="text" name="login">
<button type="submit"> Login </button>
</form>



sess2.png




Механизм выхода из сессии




В файле secret.php реализуем механизм выхода. При его работе из сессии будет удалятся сессионная переменная $_SESSION['admin'] и пользователь без авторизации не получит сюда доступ.

Ссылка для выхода из сессии:


-- файл secret.php --

<a href= "secret.php?do=exit"> Logout </a>



В результате в массиве GET (в командной строке) получим: secret.php?do=exit, то есть, у нас появится элемент do со значением exit.

Это значит, что мы можем добавить условие :


-- файл secret.php--

if ( isset ( $_GET [ 'do' ] && $_GET [ 'do' ] == 'exit' )){
unset ( $_SESSION [ 'admin' ]); // удаляем сессионную переменную
header ( "Location: sess1.php" ); // делаем редирект
die; // и завершаем выполнение скрипта
}



-если у нас существует в массиве $_GET элемент do и при этом $_GET['do'] равняется строке exit, то мы удалим сессионную переменную $_SESSION['admin'].

Далее можно опять перезапросить страницу. (редирект: header("location: sess1.php")).


sess3.png



Структура файлов урока


php19.png






Наверх Наверх