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