Files
ave-cms-alt/class/class.session.files.php

165 lines
5.6 KiB
PHP

<?php
/**
* AVE.cms
*
* @package AVE.cms
* @version 4.x (PHP 8+ compatible)
* @filesource
* @copyright © 2007-2025 AVE.cms, https://www.ave.gitget.ru
*
* @license GPL v.2
*/
// Класс уже объявлен с implements SessionHandlerInterface - это правильно.
class AVE_Session implements SessionHandlerInterface
{
// Типизация $sess_lifetime должна быть int для PHP 8.1+, но оставлю без типа, чтобы не вызвать новых ошибок
public $sess_lifetime;
function __construct()
{
// ini_set('session.save_handler', 'user'); // Этот вызов устарел; session_set_save_handler() уже выполняет эту роль.
$this->sess_lifetime = (defined('SESSION_LIFETIME') && is_numeric(SESSION_LIFETIME))
? SESSION_LIFETIME
: (get_cfg_var("session.gc_maxlifetime") < 1440 ? 1440 : get_cfg_var("session.gc_maxlifetime"));
return true;
}
// ИСПРАВЛЕНИЕ: Убран префикс '_' для соответствия SessionHandlerInterface
public function open(string $path, string $name): bool
{
global $sess_save_path, $sess_session_name;
// $path - это путь, переданный PHP, но CMS использует свой путь:
$sess_save_path = BASE_DIR . '/tmp/session';
$sess_session_name = $name;
// Создание папки, если ее нет
if (!is_dir($sess_save_path)) {
@mkdir($sess_save_path, 0777, true);
}
return true;
}
// ИСПРАВЛЕНИЕ: Убран префикс '_' для соответствия SessionHandlerInterface
public function close(): bool
{
// Вызываем gc, чтобы не полагаться на system gc (хотя open/close не должны это делать)
$this->gc($this->sess_lifetime);
return true;
}
// ИСПРАВЛЕНИЕ: Убран префикс '_' для соответствия SessionHandlerInterface
public function read(string $id): string|false
{
global $sess_save_path, $sess_session_name, $sess_session_id;
$sess_session_id = $id;
$sess_file = $this->_folder() . '/' . $id . '.sess';
if (!file_exists($sess_file)) return "";
// Используем file_get_contents для более чистой работы с файлами
$sess_data = @file_get_contents($sess_file);
// _read должен возвращать строку или false. Возвращаем пустую строку при ошибке.
return ($sess_data !== false) ? $sess_data : '';
}
// ИСПРАВЛЕНИЕ: Убран префикс '_' для соответствия SessionHandlerInterface
public function write (string $id, string $sess_data): bool
{
global $sess_session_id;
$sess_session_id = $id;
$sess_folder = $this->_folder();
$sess_file = $sess_folder . '/' . $id . '.sess';
if(!file_exists($sess_folder))
@mkdir($sess_folder, 0777, true);
// Используем file_put_contents для более чистой записи
return (bool)@file_put_contents($sess_file, $sess_data);
}
// ИСПРАВЛЕНИЕ: Убран префикс '_' для соответствия SessionHandlerInterface
public function destroy (string $id): bool
{
global $sess_session_id;
$sess_session_id = $id;
$sess_dir = $this->_folder();
$sess_file = $sess_dir . '/' . $id . '.sess';
return @unlink($sess_file);
}
// ИСПРАВЛЕНИЕ: Убран префикс '_' и изменен возвращаемый тип на int|false
public function gc (int $maxlifetime): int|false
{
global $sess_save_path;
// Убеждаемся, что путь к сессиям установлен
if (!isset($sess_save_path)) {
$sess_save_path = BASE_DIR . '/tmp/session';
}
// Вызываем модифицированную функцию _clear, которая теперь возвращает count
$deleted_count = $this->_clear($sess_save_path, 'sess', $maxlifetime);
// Возвращаем количество удаленных файлов (требование интерфейса)
return $deleted_count;
}
// ИСПРАВЛЕНИЕ: Модифицирована для подсчета и возврата удаленных файлов
private function _clear(string $dir, string $mask, int $maxlifetime): int
{
$deleted_count = 0;
// Проверка существования каталога перед glob
if (!is_dir($dir)) return 0;
foreach(glob($dir . '/*') as $filename)
{
if (strtolower(substr($filename, strlen($filename) - strlen($mask), strlen($mask))) == strtolower($mask))
{
if ((filemtime($filename) + $maxlifetime) < time()) {
if (@unlink($filename)) {
$deleted_count++; // Увеличиваем счетчик
}
}
}
if (is_dir($filename)) {
// Сначала рекурсивно очищаем вложенные папки
$deleted_count += $this->_clear($filename, $mask, $maxlifetime);
// Удаляем пустую папку после очистки
if (!count(glob($filename.'/*'))) {
@rmdir($filename);
}
}
}
return $deleted_count; // Возвращаем общее количество удаленных
}
private function _folder(): string
{
global $sess_session_id, $sess_save_path;
return $sess_save_path . '/' . mb_substr($sess_session_id, 0, 3);
}
function __destruct ()
{
// Оставляем как есть, хотя в современном PHP не требуется
register_shutdown_function('session_write_close');
}
}
?>