PHP: Przedwczesny “timeout” sesji

2012-06-28 PHP

Programując na systemie Ubuntu w PHP z wykorzystaniem sesji, często dochodzi do konieczności zwiększenia czasu życia tychże ponad standardowe 1440 sekund (24 minuty). Najczęściej robi sie to poprzez użycie funkcji ini_set():

ini_set('session.gc_maxlifetime', 21600); //6 godzin podane w sekundach

Po tym zabiegu sesja powinna się utrzymać na serwerze przez sześć godzin (bądź wcześniej – jeśli zamknięta zostanie przeglądarka internetowa). Niestety taka zmiana nie przynosi efektu i zmienna jest usuwana w przedziale od 24 do 54 minut od chwili powstania. Dlaczego? Dzieje się tak ponieważ Ubuntu nadpisuje zachowanie sesji w PHP. Korzystając z phpinfo() przeglądamy ustawienia na serwerze i odnajdujemy wartość

session.gc_probability

Jeśli jest ustawiona na 0 oznacza to, iż "garbage collector" wbudowany w PHP nie zostanie uruchomiony. Niestety zamiast tego – cyklicznie co pół godziny uruchomione zostanie zadanie cron'a, które wyczyści sesje. "Garbage collector" oparty o zadanie cron'a, bazuje na wartości session.gc_maxlifetime pobieranej z globalnego pliku php.ini, który zdaje się mieć wyższy priorytet nad wartością ustawianą przez nas w skrypcie.

Rozwiązanie problemu:

Wyłączenie cron'a i zmiana ustawień w pliku php.ini jest możliwa ale sprawia wiele kłopotów. Problem zostanie rozwiązany tylko z poziomu skryptu.

1. W skrypcie modyfikujemy trzy wartości:

  • session.gc_maxlifetime,
  • session.gc_divisor,
  • session.save_path
ini_set('session.gc_maxlifetime', 21600); //6 godzin podane w sekundach

dalej

ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);

1% szansy na to, że "garbage collector" uruchomi się przy danym wywołaniu session_start().

2. Zmieniamy domyślną lokalizacje gdzie zapisywane są sesje w PHP np. na katalog sessions naszej własnej aplikacji:

session_save_path('/sessions');

Ścieżka (która musi być inna niż domyślna) sprawi, że linuksowe zadanie cron'a nie będzie starało się jej wyczyścić. Nowy katalog z sesjami musi mieć prawa do zapisu plików (chmod). Powyższe fragmenty kodu wstawiamy przed pierwszym wywołaniem funkcji w skrypcie.

session_start();
Do NOT follow this link or you will be banned from the site!