Skip to main content

🗄️ Session-Probleme?

MODX: Session-Probleme bei session.gc_probability = 0

🔍 Überblick

MODX speichert Backend- und Frontend-Sessions in der Datenbank-Tabelle modx_session.
Der automatische Aufräumvorgang (Garbage Collector) wird von PHP gesteuert.

Wenn in deiner php.ini folgender Wert gesetzt ist:

session.gc_probability = 0

bedeutet das:

  • 🧹 Der PHP-Session-Garbage-Collector läuft nie
  • 📈 Die Tabelle modx_session wird immer größer
  • 🐌 MODX kann spürbar langsamer werden

Dieses Verhalten ist bestätigt (GitHub Issue #775).

Standardmäßig sollten die Werte so aussehen:

session.gc_probability = 1
session.gc_divisor = 1000

→ Der Garbage Collector läuft mit einer Wahrscheinlichkeit von 0,1 % pro Request.


⚠️ Symptome

  • modx_session wird immer größer
  • Datenbank wächst unnötig
  • Backend wird träge
  • Sessions bleiben endlos bestehen

🧰 Lösungen (wenn php.ini NICHT geändert werden kann)

1️⃣ Sessions per Manager löschen

Manager → Manage → LOGOUT ALL USERS

  • entfernt alle Einträge aus modx_session
  • loggt alle Benutzer sofort aus

2️⃣ UpgradeMODX verwenden

Das MODX-Package UpgradeMODX führt beim Upgrade:

  • Cache-Löschung
  • Session-Bereinigung
  • Löschen des ~/core/cache Ordners

Dadurch wird auch modx_session geleert.


3️⃣ Plugin delAllSessions erstellen (empfohlen)

Erstellt ein Plugin, das alte Sessions automatisch löscht.
Bei Bedarf können auch alle Sessions beim Clear Cache gelöscht werden.

Elemente → Plugins → Neu
System-Events:

  • OnManagerLogin
  • OnCacheUpdate (Achtung!)
📌 Plugin-Code
<?php
# delete sessions (sql-table modx_session)
# https://github.com/modxcms/revolution/issues/775
# System Events: OnManagerLogin, OnCacheUpdate

# delete old sessions after Manager Login
# this isn't necessary if php.ini "session.gc_probability = 1"

if ($modx->event->name == 'OnManagerLogin') {
    # $modx->log(modX::LOG_LEVEL_ERROR, '[delAllSessions] Info: table old modx_session deleted');

    $gcMaxlifetime = (integer) $modx->getOption('session_gc_maxlifetime', null, @ini_get('session.gc_maxlifetime'), true);
    $access = time() - $gcMaxlifetime;
    $modx->exec("
        DELETE FROM {$modx->getTableName('modSession')} WHERE `access` < {$access};
        OPTIMIZE TABLE {$modx->getTableName('modSession')};
    ");
}

# ATTENTION! this delete all sessions by Menu -> Manage -> Clear Cache
# please use only if you know what you are doing!

if ($modx->event->name == 'OnCacheUpdate') {
    # $modx->log(modX::LOG_LEVEL_ERROR, '[delAllSessions] Info: table all modx_session deleted');

    $modx->exec("
        DELETE FROM {$modx->getTableName('modSession')};
        OPTIMIZE TABLE {$modx->getTableName('modSession')};
    ");
}

Das Plugin führt zwei Aktionen aus:

  1. Beim Login im Manager (Event: OnManagerLogin) werden alle abgelaufenen Sessions aus der Tabelle modx_session gelöscht. Als Referenz dient der Wert aus session_gc_maxlifetime. Danach wird die Tabelle optimiert.

  2. Beim Leeren des Caches (Event: OnCacheUpdate) werden alle vorhandenen Sessions vollständig gelöscht – unabhängig vom Alter – und die Tabelle wird ebenfalls optimiert.
    ⚠️ Bitte nur verwenden, wenn du weisst was du tust!
    Wenn du das nicht willst, aktiviere OnCacheUpdate nicht.


📌 Empfehlung

  1. Wenn möglich, php.ini anpassen:

    session.gc_probability = 1
    session.gc_divisor = 1000
    
  2. Wenn nicht möglich:

    • Plugin „delAllSessions“ aktivieren
    • gelegentlich „Logout All Users“ ausführen
    • UpgradeMODX nutzen, um Sessions aufzuräumen

✅ Fazit

session.gc_probability = 0 verhindert, dass PHP Sessions automatisch löscht.
Dadurch wächst modx_session endlos.
Mit den oben beschriebenen Methoden kannst du das Problem zuverlässig beheben – auch ohne Zugriff auf die php.ini.