Sprawiamy, że nasza funkcjonalność sprawdzania ilu użytkowników jest na stronie działa w pełni poprawnie. Do dzieła.

Poprzednio stanęliśmy na tym:

<?php
class Session
{
 
  //(...)


  public static function sessions5Minutes(){
    
    $session_path = session_save_path();
    $handle = opendir($session_path);
    $sessions = 0;

        while (($file = readdir($handle)) != FALSE) {
           
            if(in_array($file, ['.', '..']))
                continue;
            if(!preg_match("/^sess/", $file))
                continue;
           
            $file_path = "{$session_path}/{$file}";
            $last_access = date("Y-m-d H:i:s", fileatime($file_path));
            $now = date("Y-m-d H:i:s", strtotime("-5 minutes"));
            
            if($now <= $last_access)
                $sessions++;
            
        }
    return $sessions;
}
}


Session::start();
echo Session::sessions5Minutes();
//1

I możliwe, że jeżeli otworzymy w nowej przeglądarce nasze okno utworzony zostanie plik sesji i jego data ostatniego accessu będzie się mieścić w minus 5 minut i liczba się nam o 1 zwiększy.

Możliwe też, że mamy tam już sesję istniejącą zaś dane dotyczące ostatniego accessu do tego już istniejącego pliku są w cache jako 'stale’.

Rozwiązanie:

<?php
class Session
{
 
  //(...)


  public static function sessions5Minutes(){
    
    $session_path = session_save_path();
    $handle = opendir($session_path);
    $sessions = 0;
    clearstatcache();

        while (($file = readdir($handle)) != FALSE) {
           
            if(in_array($file, ['.', '..']))
                continue;
            if(!preg_match("/^sess/", $file))
                continue;
           
            $file_path = "{$session_path}/{$file}";
            $last_access = date("Y-m-d H:i:s", fileatime($file_path));
            $now = date("Y-m-d H:i:s", strtotime("-5 minutes"));
            
            if($now <= $last_access)
                $sessions++;
            
        }
    return $sessions;
}
}

Ok, czyścimy kesz, nowe dane mamy. Co jednak jeśli użytkownik nadal jest na stronie, odświeżył 5 sekund temu, ale po prostu data ostatniego odczytu z pliku sesyjnego jest starsza niż te 5 minut bo przez te 5 minut nic do sesji nie było zapisywane ani z niej odczytywane?

Cóż, i to można naprawić:

<?php
class Session
{
 
  //(...)


  public static function sessions5Minutes(){
    
    $session_path = session_save_path();
    $handle = opendir($session_path);
    $sessions = 0;
    clearstatcache();
    static::set("_cache", (string)time());

        while (($file = readdir($handle)) != FALSE) {
           
            if(in_array($file, ['.', '..']))
                continue;
            if(!preg_match("/^sess/", $file))
                continue;
           
            $file_path = "{$session_path}/{$file}";
            $last_access = date("Y-m-d H:i:s", fileatime($file_path));
            $now = date("Y-m-d H:i:s", strtotime("-5 minutes"));
            
            if($now <= $last_access)
                $sessions++;
            
        }
    return $sessions;
}
}

Zapisujemy coś do sesji, zatem wymuszamy access do pliku sesyjnego (samo session_create w żaden sposób tego nie aktualizuje, jeżeli sesja już jest). Na razie jednak robimy to tylko na tej stronie, która podlicza aktywnych użytkowników.

Czytaj – zobaczysz ilu użytkowników gapi się na licznik aktywnych użytkowników. Nie – ilu na całej twojej stronie w tym czy innym miejscu przebywa.

Jeszcze nie znamy konceptu middleware, którego będziemy używać w naszym projekcie MVC, więc na razie proponuję takie rozwiązanie:

<?php
class Session
{
 
  //(...)

public static function onEveryRequestMiddleware(){
    static::start();
    static::set("_cache", (string)time());
}
}


Session::onEveryRequestMiddleware();
echo Session::sessions5Minutes();
//3

Jeżeli tę metodę wywołamy na każdej naszej stronie symulując coś takiego jak middleware, to każde odświeżenie jakiejkolwiek strony wiąże się z utworzeniem sesji jeśli ta nie istnieje i próbą dostępu do jej pliku sesyjnego, dzięki czemu możemy mieć idealnie działający mechanizm pokazywania ilości użytkowników online.