Функции сессий Albireo CMS
Функция sentLast
Функция sentLast реализует механизм ограничения частоты отправки форм (rate-limiting) для неавторизованных (гостевых) пользователей. Она помогает защититься от простого спама и случайных двойных отправок, заставляя пользователя выдерживать паузу между запросами.
Сигнатура
function sentLast(int|bool $delay = 0): int
Аргументы
- int|bool
$delay(необязательный) Этот параметр определяет режим работы функции:
true(логическое): Режим установки/сброса. Функция записывает в сессию текущее время как время последней отправки. Это следует делать после успешной обработки формы.0(целое число, по умолчанию): Режим проверки. Функция использует задержку, указанную в конфигурации сайта (getConfig('sentDelay', 120)).int > 0(целое число): Режим проверки с пользовательской задержкой. Функция использует переданное значение в качестве задержки в секундах.
Результат
Возвращает целое число (int):
0— если отправка формы разрешена. Это происходит, если:- Пользователь авторизован.
- С момента последней отправки прошло достаточно времени.
- Это первая отправка в текущей сессии.
- Функция была вызвана в режиме установки (
$delay === true).
> 0— если отправка запрещена. Возвращаемое число — это количество секунд, которое необходимо подождать до следующей попытки.
Примеры использования
Пример: Полный цикл обработки формы с защитой
Это наиболее полный и правильный сценарий использования функции в файле-обработчике формы.
// form-handler.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 1. Проверяем, можно ли сейчас отправлять форму.
if ($waitTime = sentLast()) {
die(sprintf('Вы отправляете сообщения слишком часто. Пожалуйста, подождите %d сек.', $waitTime));
}
// 2. Если проверка пройдена, выполняем валидацию и обработку данных.
// ...
// $data_is_valid = validate_form($_POST);
// ...
if ($data_is_valid) {
// 3. После успешной обработки данных, сбрасываем таймер.
sentLast(true);
// 4. Перенаправляем пользователя, чтобы избежать повторной отправки.
header('Location: /thank-you.php');
exit;
}
}
Примечания
- Для гостей: Механизм задержки работает только для неавторизованных пользователей. Для залогиненных пользователей функция всегда возвращает
0.
Функция sessionFlashGet
Функция sessionFlashGet используется для получения "flash-сообщения" из сессии. Ключевой особенностью является то, что после получения сообщения оно по умолчанию удаляется, гарантируя, что оно будет показано пользователю только один раз. Эта функция является неотъемлемой частью механизма flash-сообщений и используется в паре с sessionFlashSet().
Сигнатура
function sessionFlashGet(string $key, bool $delete = true): mixed
Аргументы
- string
$key - Ключ, по которому нужно получить flash-сообщение.
- bool
$delete(необязательный) - Определяет, нужно ли удалять сообщение из сессии после его прочтения. Если
true(по умолчанию), сообщение будет удалено. Еслиfalse, сообщение останется в сессии, что может быть полезно для отладки или в редких случаях, когда одно и то же сообщение нужно показать на нескольких страницах.
Результат
Возвращает значение (mixed), сохраненное в flash-сессии по указанному ключу. Если ключ не найден, возвращается пустая строка ''.
Примеры использования
Пример: Отображение сообщений после обработки формы
Это классический сценарий использования flash-сообщений. Пример является продолжением примера для функции sessionFlashSet().
Файл страницы настроек (settings.php), куда происходит редирект:
// ... здесь HTML-код страницы ...
// Пытаемся получить и отобразить flash-сообщение об успехе.
// Если сообщение будет найдено, оно сразу же удалится из сессии.
if ($message = sessionFlashGet('success')) {
echo '<div class="alert alert-success">' . htmlspecialchars($message) . '</div>';
}
// Пытаемся получить и отобразить flash-сообщение об ошибке.
if ($message = sessionFlashGet('error')) {
echo '<div class="alert alert-danger">' . htmlspecialchars($message) . '</div>';
}
// При обновлении страницы (F5) эти сообщения уже не появятся.
// ... остальной HTML-код ...
Пример 2: "Подглядывание" сообщения без удаления
В редких случаях может потребоваться проверить наличие сообщения, не удаляя его.
// Проверяем, есть ли сообщение об ошибке, для добавления специального CSS-класса
$hasError = (bool) sessionFlashGet('error', false); // false - не удалять
if ($hasError) {
echo '<body class="page-with-errors">';
} else {
echo '<body>';
}
// ... позже в коде можно будет получить это же сообщение для вывода
$errorMessage = sessionFlashGet('error'); // теперь уже с удалением
if ($errorMessage) {
// ... вывод сообщения ...
}
Примечания
- Парная функция: Эта функция всегда используется в паре с
sessionFlashSet(), которая отвечает за установку сообщения. - Значение по умолчанию: При отсутствии ключа функция возвращает пустую строку
'', а неnull.
Функция sessionFlashSet
Функция sessionFlashSet используется для установки "flash-сообщения" — временного сообщения, которое будет доступно только на следующей загрузке страницы. После того как сообщение будет прочитано (с помощью парной функции sessionFlashGet), оно автоматически удаляется из сессии. Это стандартный паттерн для отображения уведомлений после выполнения какого-либо действия и последующего редиректа.
Сигнатура
function sessionFlashSet(string $key, mixed $val): void
Аргументы
- string
$key - Ключ, по которому будет сохранено flash-сообщение. Обычно используются ключи, отражающие тип сообщения, например,
'success','error','warning'. - mixed
$val - Данные для сохранения. Чаще всего это строка с текстом сообщения, но может быть и массив или другой тип данных.
Результат
Функция ничего не возвращает (void). Её результат — это запись данных в сессию.
Примеры использования
Пример: Отображение сообщения после обработки формы
Это классический сценарий использования flash-сообщений с применением паттерна Post/Redirect/Get.
1. Файл-обработчик формы (например, save-settings.php):
// ... здесь происходит валидация и сохранение данных ...
if ($success) {
// Устанавливаем сообщение об успехе
sessionFlashSet('success', 'Настройки успешно сохранены!');
} else {
// Устанавливаем сообщение об ошибке
sessionFlashSet('error', 'Произошла ошибка при сохранении настроек.');
}
// Перенаправляем пользователя обратно на страницу настроек
header('Location: /settings.php');
exit;
2. Файл страницы настроек (settings.php), куда происходит редирект:
// ... здесь HTML-код страницы ...
// Пытаемся получить и отобразить flash-сообщение об успехе
if ($message = sessionFlashGet('success')) {
echo '<div class="alert alert-success">' . htmlspecialchars($message) . '</div>';
}
// Пытаемся получить и отобразить flash-сообщение об ошибке
if ($message = sessionFlashGet('error')) {
echo '<div class="alert alert-danger">' . htmlspecialchars($message) . '</div>';
}
// ... остальной HTML-код ...
Примечания
- Парная функция: Эта функция всегда используется в паре с
sessionFlashGet(), которая отвечает за чтение и последующее удаление сообщения. - Неймспейс в сессии: Все flash-сообщения хранятся в сессии под специальным ключом
_flash, чтобы избежать конфликтов с другими данными сессии. - Источник: https://maxsite.org/page/php-flash-message
Функция sessionOld
Функция sessionOld предоставляет простой интерфейс для работы с сессией, совмещая в себе функциональность "геттера" и "сеттера". В зависимости от наличия второго аргумента, она либо записывает данные в сессию, либо считывает их.
Сигнатура
function sessionOld(string $key, mixed $val = null): mixed
Аргументы
- string
$key - Ключ сессии, по которому осуществляется доступ к данным.
- mixed|null
$val(необязательный) - Значение для установки. Если этот аргумент не передан или равен
null, функция работает в режиме получения данных. В противном случае — в режиме установки.
Результат
Возвращаемое значение зависит от режима работы:
- При получении данных (когда
$valравенnull): возвращает значение, хранящееся в сессии по ключу$key. Если ключ не существует, возвращается пустая строка''. - При установке данных: функция ничего не возвращает (неявно
null).
Примеры использования
Основные примеры см. в pages/specific/demo.
Пример: Сохранение и получение "старых" данных формы
Эта функция полезна для повторного заполнения полей формы после неудачной валидации, чтобы пользователю не приходилось вводить все данные заново.
// --- form_handler.php ---
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Сохраняем все отправленные данные в сессию
sessionOld('old_form_data', $_POST);
// ... здесь идет валидация ...
if (/ * валидация не пройдена * /) {
// Перенаправляем пользователя обратно на форму
header('Location: /my-form.php');
exit;
}
// ... успешная обработка ...
}
// --- my-form.php ---
// Получаем "старые" данные. Если их нет, будет пустой массив.
$oldData = sessionOld('old_form_data') ?: [];
// Удаляем данные из сессии, чтобы они не остались там навсегда
unset($_SESSION['old_form_data']);
// ... HTML-код формы ...
<form method="post" action="/form_handler.php">
<input type="text" name="username"
value="<?= htmlspecialchars($oldData['username'] ?? '') ?>">
<input type="email" name="email"
value="<?= htmlspecialchars($oldData['email'] ?? '') ?>">
<button type="submit">Отправить</button>
</form>
Функция sessionStart
Функция sessionStart является ключевым компонентом инициализации системы. Она отвечает за безопасный запуск и конфигурацию PHP-сессий, а также за создание и управление CSRF-токеном для защиты от межсайтовой подделки запросов.
Сигнатура
function sessionStart(): void
Аргументы
Функция не принимает аргументов.
Результат
Функция ничего не возвращает (void). Её работа заключается в изменении глобального состояния:
- Запускается PHP-сессия (
session_start()) с набором безопасных параметров. - В сессии
$_SESSIONсоздается или обновляется ключcsrf_token. - Определяется глобальная константа
SESSION_TOKEN, содержащая значение CSRF-токена.
В случае критической ошибки (если сессию не удалось запустить), функция прерывает выполнение скрипта.
Примеры использования
Пример: Использование созданного CSRF-токена
После вызова sessionStart(), константа SESSION_TOKEN становится доступна по всему приложению для защиты форм.
<!-- form.php -->
<form method="POST" action="/submit">
<label for="username">Имя пользователя:</label>
<input type="text" id="username" name="username">
<!-- Вставляем скрытое поле с токеном -->
<input type="hidden" name="_token" value="<?= SESSION_TOKEN ?>">
<button type="submit">Отправить</button>
</form>
Примечания
- Безопасность: Функция устанавливает важные параметры безопасности для сессионных cookie, такие как
httponly(защита от доступа через JavaScript),use_strict_mode(защита от фиксации сессии) иsamesite='Lax'(защита от CSRF). - Конфигурация: Время жизни cookie (
cookie_lifetime) и время жизни сессии на сервере (gc_maxlifetime) настраиваются через функциюgetConfig(). - Хранение сессий: Путь для хранения файлов сессий может быть задан через константу
SESSIONS_DIR. - CSRF-токен: Токен генерируется с помощью криптографически безопасной функции
random_bytes(). Он пересоздается, если отсутствует в сессии или был помечен как невалидный (через ключ$_SESSION['csrf_token_invalid']).
Функция sessionUnsetCSRF
Функция sessionUnsetCSRF помечает текущий CSRF-токен как недействительный. Это достигается путем установки специального флага в сессии ($_SESSION['csrf_token_invalid']). При следующем запуске сессии (как правило, на следующей странице), функция sessionStart() обнаружит этот флаг и сгенерирует новый CSRF-токен, делая старый недействительным.
Это важный механизм для повышения безопасности и предотвращения повторной отправки данных формы.
Сигнатура
function sessionUnsetCSRF(): void
Аргументы
Функция не принимает аргументов.
Результат
Функция ничего не возвращает (void). Её результат — это изменение состояния сессии.
Примечания
- Зависимости: Функция напрямую работает с глобальным массивом
$_SESSIONи является частью механизма, управляемого функциейsessionStart(). - Безопасность: Использование этой функции в сочетании с паттерном Post/Redirect/Get является хорошей практикой для защиты веб-приложений от множества проблем, включая случайную повторную отправку данных пользователем.