По сравнению с Cookie, Session — это серверная сессия, относительно безопасная, и, в отличие от Cookie, у неё нет ограничения на длину хранения. В этой статье кратко описывается использование Session.

Поскольку Session хранится на сервере в виде текстовых файлов, нет опасения, что клиенты изменят содержимое Session. Фактически для файлов Session на сервере PHP автоматически изменяет права доступа к файлам, оставляя только системные права на чтение и запись, и их нельзя изменить через FTP, поэтому это гораздо безопаснее.

Для Cookie предположим, мы хотим проверить, вошёл ли пользователь в систему. Мы должны хранить имя пользователя и пароль (возможно, md5-зашифрованную строку) в Cookie и проверять их при каждом запросе страницы. Если имя пользователя и пароль хранятся в базе данных, при каждом разе придётся выполнять запрос к базе данных, что создаёт ненужную нагрузку на базу данных. Потому что мы не можем проверить только один раз. Почему? Потому что информацию в клиентском Cookie можно изменить. Предположим, вы храните переменную $admin, чтобы указывать, вошёл ли пользователь в систему. Когда $admin истинна, это означает, что пользователь вошёл; когда ложна — не вошёл. После первой успешной проверки вы сохраняете $admin равной true в Cookie, и в следующий раз проверка не нужна. Правильно ли это? Неправильно. Если кто-то подделает переменную $admin со значением true, разве он немедленно не получит административные права? Это очень небезопасно.

Session отличается. Session хранится на стороне сервера, поэтому удалённые пользователи не могут изменять содержимое файлов Session. Следовательно, мы можем просто хранить переменную $admin, чтобы определять, вошёл ли пользователь в систему. После первой успешной проверки установите $admin в true. Позже проверяйте, истинно ли это значение; если нет, перенаправьте на страницу входа. Это может сократить множество операций с базой данных. Это также снижает небезопасность передачи паролей каждый раз при проверке Cookie (при проверке Session их нужно передавать только один раз, если вы не используете протокол безопасности SSL). Даже если пароль зашифрован md5, его легко перехватить.

Конечно, использование Session имеет много других преимуществ, например, простое управление и возможность настраивать хранение в соответствии с пользователем (например, хранить в базе данных). Здесь я не буду вдаваться в подробности.

Нужно ли настраивать сессию в php.ini? Обычно нет, потому что не у всех есть разрешение изменять php.ini. Путь хранения сессии по умолчанию — системная временная папка сервера. Мы можем настроить её так, чтобы она сохранялась в нашей собственной папке, о чём я расскажу позже.

Теперь давайте рассмотрим, как создать сессию. Это очень просто, на самом деле.

Запустите сессию и создайте переменную $admin:

Пример

<?php
// Запуск сессии
session_start();
// Объявить переменную с именем admin и присвоить пустое значение.
$_SESSION["admin"] = null;
?>

Если вы используете сессию или если этому PHP-файлу нужно обращаться к переменным сессии, вы должны запустить её перед обращением к сессии с помощью функции session_start(). Вам не нужно настраивать что-либо ещё; PHP автоматически создаёт файл сессии.

После выполнения этой программы мы можем перейти в системную временную папку, чтобы найти этот файл сессии. Обычно имя файла выглядит так: sess_4c83638b3b0dbf65583181c2f89168ec, за ним следует 32-битная закодированная случайная строка. Откройте его в редакторе и посмотрите его содержимое:

admin|N;

Обычно содержимое имеет следующую структуру:

variable name|type:length:value;

Каждая переменная разделяется точкой с запятой. Некоторые части можно опустить, например длину и тип.

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

Код файла login.php

<?php
// После отправки формы...
$posts = $_POST;
// Удалить некоторые пробельные символы
foreach ($posts as $key => $value) {
    $posts[$key] = trim($value);
}
$password = md5($posts["password"]);
$username = $posts["username"];

$query = "SELECT `username` FROM `user` WHERE `password` = '$password' AND `username` = '$username'";
// Получить результат запроса
$userInfo = $DB->getRow($query);

if (!empty($userInfo)) {
    // Запустить сессию после успешной проверки
    session_start();
    // Зарегистрировать переменную admin для успешного входа и присвоить true
    $_SESSION["admin"] = true;
} else {
    die("Неверное имя пользователя или пароль");
}
?>

На страницах, требующих аутентификации пользователя, мы запускаем сессию и определяем, вошёл ли пользователь в систему:

Пример

<?php
// Предотвратить риски безопасности, вызванные глобальными переменными
$admin = false;
// Запустить сессию, этот шаг обязателен
session_start();
// Определить, вошёл ли пользователь в систему
if (isset($_SESSION["admin"]) && $_SESSION["admin"] === true) {
    echo "Вы успешно вошли в систему";
} else {
    // Проверка не пройдена, установите $_SESSION["admin"] в false
    $_SESSION["admin"] = false;
    die("У вас нет прав на доступ");
}
?>

Разве это не просто? Просто представьте $_SESSION как массив, хранящийся на стороне сервера. Каждая переменная, которую мы регистрируем, — это ключ массива, как при использовании массива.

Что делать, если вы хотите выйти из системы? Просто уничтожьте сессию.

Пример

<?php
session_start();
// Этот метод уничтожает ранее зарегистрированную переменную
unset($_SESSION['admin']);
// Этот метод уничтожает весь файл сессии
session_destroy();
?>

Может ли сессия задавать время жизни, как куки? При использовании сессии стоит ли полностью отказаться от куки? Я бы сказал, что использовать сессию в сочетании с куки наиболее удобно.

Как сессия идентифицирует клиентского пользователя? Она идентифицируется по ID сессии. Что такое ID сессии? Это имя файла того файла сессии. ID сессии генерируется случайным образом, что обеспечивает уникальность и случайность, а также безопасность сессии. Обычно, если время жизни сессии не задано, ID сессии хранится в памяти. После закрытия браузера ID автоматически аннулируется, и после повторного запроса страницы регистрируется новый ID сессии.

Если клиент не отключает куки, куки играют роль хранилища ID сессии и времени жизни сессии при запуске сессии.

Давайте вручную зададим время жизни сессии:

Пример

<?php
session_start();
// Сохранить на один день
$lifeTime = 24 * 3600;
setcookie(session_name(), session_id(), time() + $lifeTime, "/");
?>

На самом деле, сессия также предоставляет функцию session_set_cookie_params(); для установки времени жизни сессии. Эта функция должна быть вызвана до вызова функции session_start():

Пример

<?php
// Сохранить на один день
$lifeTime = 24 * 3600;
session_set_cookie_params($lifeTime);
session_start();
$_SESSION["admin"] = true;
?>

Если клиент использует IE 6.0, функция session_set_cookie_params(); может иметь некоторые проблемы с установкой куки, поэтому мы всё равно вручную вызываем функцию setcookie для создания куки.

Что если клиент отключает куки? Обойти это невозможно; все сроки жизни привязаны к процессу браузера. Как только браузер закрывается, при повторном запросе страницы вам придётся заново регистрировать сессию. Так как же передать ID сессии? Передайте его через URL или через скрытую форму. PHP автоматически отправляет ID сессии в URL. URL выглядит так: http://www.test.cn/index.php?PHPSESSID= bba5b2a240a77e5b44cfa01d49cf9669, где параметр PHPSESSID в URL — это ID сессии. Мы можем использовать $_GET, чтобы получить это значение, тем самым передавая ID сессии между страницами.

Пример

<?php
// Сохранить на один день
$lifeTime = 24 * 3600;
// Получить текущее имя сессии, по умолчанию PHPSESSID
$sessionName = session_name();
// Получить ID сессии
$sessionID = $_GET[$sessionName];
// Используйте session_id() для установки полученного идентификатора сессии
session_id($sessionID);

session_set_cookie_params($lifeTime);
session_start();
$_SESSION['admin'] = true;
?>

Для виртуальных хостов, если сессии всех пользователей сохраняются в системной временной папке, это вызовет сложности в обслуживании и снизит безопасность. Мы можем вручную задать путь сохранения файлов сессий. session_save_path() предоставляет такую функцию. Мы можем указать каталог хранения сессий в папку, недоступную через веб. Конечно, папка должна иметь права на чтение и запись.

Пример

<?php
// Установить каталог хранения
$savePath = './session_save_dir/';
// Сохранить на один день
$lifeTime = 24 * 3600;
session_save_path($savePath);
session_set_cookie_params($lifeTime);
session_start();
$_SESSION['admin'] = true;
?>

Как и функцию session_set_cookie_params();, функцию session_save_path() также нужно вызывать перед функцией session_start().

Мы также можем хранить массивы и объекты в сессии. Работа с массивами ничем не отличается от работы с обычными переменными, но при сохранении объектов PHP автоматически сериализует (это также называется сериализацией) объекты и затем сохраняет их в сессии. Следующий пример иллюстрирует это:

Код файла person.php

<?php
class person {
    var $age;
    function output() {
        echo $this->age;
    }
    function setAge($age) {
        $this->age = $age;
    }
}
?>

setage.php код файла

<?php
session_start();
require_once 'person.php';
$person = new person();
$person->setAge(21);
$_SESSION['person'] = $person;
echo '<a href='output.php'>нажмите здесь, чтобы вывести возраст</a>';
?>

output.php код файла

<?php
// Задайте функцию обратного вызова, чтобы гарантировать пересоздание объекта.
ini_set('unserialize_callback_func', 'mycallback');
function mycallback($classname) {
    include_once $classname . '.php';
}
session_start();
$person = $_SESSION['person'];
// Вывод 21
$person->output();
?>

Когда мы выполняем файл setage.php, мы вызываем метод setage(), устанавливаем возраст равным 21 и сериализуем это состояние перед сохранением его в сессию (PHP автоматически выполнит это преобразование). Когда мы переходим к output.php, чтобы вывести это значение, мы должны десериализовать только что сохранённый объект. А поскольку десериализация требует создания экземпляра неопределённого класса, мы определили callback-функцию, чтобы автоматически подключать файл класса person.php, поэтому объект восстанавливается, и текущее значение возраста получается равным 21, затем вызывается метод output() для вывода этого значения.

Кроме того, мы также можем использовать функцию session_set_save_handler, чтобы настроить способ вызова сессии.

Исходный адрес: https://www.cnblogs.com/happyforev1/articles/1645916.html