Как изменить место хранения сессии в PHP?

«Как изменить место хранения сессии в PHP?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Место хранения данных сессии в PHP можно изменить несколькими способами, в зависимости от требуемого хранилища (файловая система, Redis, Memcached, база данных).

1. Изменение файлового пути (по умолчанию): Используйте функцию session_save_path() перед session_start().

// Установка пользовательского пути для файлов сессий
session_save_path('/var/custom/session_dir');
// Убедитесь, что веб-сервер (www-data, nginx) имеет права на запись в эту директорию
session_start();

Или через php.ini: session.save_path = "/var/custom/session_dir".

2. Использование Redis (рекомендуется для распределенных систем): Настройте обработчик через session_set_save_handler() или, проще, через php.ini.

// Способ через php.ini (в коде или .htaccess)
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379?auth=your_password&timeout=2.5');
// Можно использовать Unix socket: 'unix:///var/run/redis/redis.sock?persistent=1'
session_start();

3. Использование пользовательского обработчика (например, для БД): Нужно реализовать интерфейс SessionHandlerInterface.

class DatabaseSessionHandler implements SessionHandlerInterface {
    private $pdo;
    public function __construct(PDO $pdo) { $this->pdo = $pdo; }
    public function open($savePath, $sessionName): bool {
        return true;
    }
    public function close(): bool {
        return true;
    }
    public function read($sessionId): string {
        $stmt = $this->pdo->prepare('SELECT data FROM sessions WHERE id = ?');
        $stmt->execute([$sessionId]);
        return (string) $stmt->fetchColumn();
    }
    public function write($sessionId, $data): bool {
        $stmt = $this->pdo->prepare(
            'REPLACE INTO sessions (id, data, access) VALUES (?, ?, ?)'
        );
        return $stmt->execute([$sessionId, $data, time()]);
    }
    // ... реализации destroy и gc
}
// Регистрация обработчика
$handler = new DatabaseSessionHandler($pdoConnection);
session_set_save_handler($handler, true);
session_start();

Критически важные моменты:

  • Безопасность: При использовании сетевых хранилищ (Redis) настройте аутентификацию и TLS.
  • Производительность: Redis/Memcached значительно быстрее файловой системы при высокой нагрузке.
  • Сборка мусора: Для нестандартных обработчиков нужно реализовать или отключить (session.gc_probability = 0) сборку мусора и чистить данные cron-задачей.