Liczba zalogowanych użytkowników

0

Witam. Mam stronę na której umieściłem kod zliczający liczbę zalogowanych użytkowników. Wszystko działa prawie dobrze. Kiedy użytkownik się zaloguje jest wyświetlana jego nazwa oraz innych użytkowników, którzy są zalogowani. Kiedy się wyloguje, odejmuje mnie w liczniku.
Natomiast gdy jestem zalogowany, a wejdę z innego komputera na stronę, to licznik się zeruje. Zmienia statusy wszystkich userów w bazie danych z "zalogowany" na "wylogowany" i zeruje tym samym licznik. Jak to mogę naprawić ? Poniżej podaję cały ten kod.

session_start();

if (isset($_SESSION['username'])) {
    // Użytkownik jest zalogowany

    // Aktualizacja statusu użytkownika na "zalogowany"
    $username = $_SESSION['username'];
    $sql = "UPDATE users SET status = 'zalogowany' WHERE username = '$username'";
    $result = $conn->query($sql);

    // Sprawdzenie czy aktualizacja się powiodła
    if ($result) {
        // Pobranie liczby zalogowanych użytkowników z bazy danych
        $sql = "SELECT COUNT(*) AS liczba_zalogowanych FROM users WHERE status = 'zalogowany'";
        $result = $conn->query($sql);
        $row = $result->fetch_assoc();
        $liczba_zalogowanych = $row['liczba_zalogowanych'];

        echo "Liczba zalogowanych użytkowników: " . $liczba_zalogowanych;

        echo "<br><br>";

        // Pobranie listy zalogowanych użytkowników z bazy danych
        $sql = "SELECT username FROM users WHERE status = 'zalogowany'";
        $result = $conn->query($sql);

        if ($result->num_rows > 0) {
            echo "Zalogowani użytkownicy: ";
            while ($row = $result->fetch_assoc()) {
                echo '<span style="color: #5F9EA0;">' . $row['username'] . '</span>, ';
            }
        } else {
            echo "Brak zalogowanych użytkowników.";
        }
    } else {
        echo "Błąd aktualizacji statusu użytkownika.";
    }
} else {
    // Użytkownik niezalogowany

    // Aktualizacja statusu użytkowników na "wylogowany"
    $sql = "UPDATE users SET status = 'wylogowany' WHERE username != 'guest' AND status = 'zalogowany'";
    $result = $conn->query($sql);

    // Sprawdzenie czy aktualizacja się powiodła
    if ($result) {
        // Pobranie liczby zalogowanych użytkowników z bazy danych (dla niezalogowanych)
        $sql = "SELECT COUNT(*) AS liczba_zalogowanych FROM users WHERE status = 'zalogowany'";
        $result = $conn->query($sql);
        $row = $result->fetch_assoc();
        $liczba_zalogowanych = $row['liczba_zalogowanych'];

        echo "Liczba zalogowanych użytkowników: " . $liczba_zalogowanych;
    } else {
        echo "Błąd aktualizacji statusu użytkowników.";
    }
}

$conn->close();

screenshot-20230531125438.png screenshot-20230531130658.png

LINK DO STRONY

3

W linijce 42 masz przecież taki update.
Prześledź sobie jak tworzy się sesja. Na nowym komputerze jak się nie zalogujesz to nie masz jeszcze sesji.
Pro tip: zamiast robić w bazie status słownie możesz zrobić kolumnę is_loggedin i dać statusy 0/1 trochę bajtów na dysku oszczędzisz, a i czytelniejsze może być.

0

Mam rozumieć że kod w linijce 42 jest dobry ? Wszystko było by dobrze, tylko to że gość wchodzi i zeruje sie licznik, mimo że ktoś jest zalogowany.

8

Mam rozumieć że kod w linijce 42 jest dobry ?

Nie - zauważ, że to zapytanie w linijce 42 zaktualizuje stan wszystkich użytkowników i zmieni ich z zalogowany na wylogowany.

IMO w ogóle masz złe podejście, bo !isset($_SESSION['username']) wcale nie oznacza, że ktoś się właśnie wylogował (jak zdajesz się to interpretować); tak na moje, w tabeli z użytkownikami powinieneś mieć kolumnę ostatnia_akcja datetime (aktualizowaną co chwilę dla każdego danego użytkownika gdy wykona on jakąś akcję na stronie), która pozwoli Ci na oszacowanie aktywnych użytkowników w taki sposób:

select count(*) from uzytkownicy where ostatnia_akcja >= now() - interval '15 minutes'

Bez zabawy w JS + WebSocket ciężko będzie o coś lepszego niż takie przybliżenie, bo HTTP jest protokołem bezstanowym - tj. serwer nie otrzymuje informacji w stylu użytkownik zamknął kartę, a jedynie zapytania użytkownik prosi o stronę /foo/bar.html; miarę aktywności użytkowników można zatem jedynie szacować wykorzystując informacje o tym kiedy dany użytkownik poprosił o jakąś stronę po raz ostatni.

1

Możesz zrobić coś takiego, że kliniięcię na każdą stronę jest zapisywane w bazie i teraz jak dla użytkownika xxxyyy czas ostatniego wejścia na stronę jakąkolwiek będzie > 15 minut to system uzna go za wylogowanego.

0

Poprawiłem, teraz druga część kodu wygląda tak:

		// Zapytanie SQL (dla użytkowników niezalogowanych)
		try {
			$sql = "SELECT COUNT(*) AS liczba_zaktualizowanych FROM users WHERE ostatnia_akcja >= NOW() - INTERVAL 1 MINUTE";
			$result = $conn->query($sql);

			if ($result) {
				$row = $result->fetch_assoc();
				$liczba_zaktualizowanych = $row['liczba_zaktualizowanych'];
				echo "Liczba zalogowanych użytkowników: " . $liczba_zaktualizowanych;
			} else {
				echo "Błąd zapytania SQL.";
			}
		} catch (Exception $e) {
			echo "Wystąpił błąd: " . $e->getMessage();
		}

Ale nie działa mi to, licznik pokazuje 0 zalogowanych.

1

Pokaż cały kod wraz z tym gdzie zapisujesz te dane do bazy.

0
jurek1980 napisał(a):

Pokaż cały kod wraz z tym gdzie zapisujesz te dane do bazy.

Ale czego kod ? Tutaj podałem cały jaki mam dotyczący tego licznika.

2
FukurouPL napisał(a):
jurek1980 napisał(a):

Pokaż cały kod wraz z tym gdzie zapisujesz te dane do bazy.

Ale czego kod ? Tutaj podałem cały jaki mam dotyczący tego licznika.

W linijce 3 tego kodu robisz SELECT zliczający ilość wierszy z zapisanym czasem i jego różniącą względem obecnego. Żeby to działało gdzieś musisz ten czas zapisywać.
BTW odpowiadaj w postach.

1 użytkowników online, w tym zalogowanych: 0, gości: 1