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

165 lines
5.6 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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');
}
}
?>