Liczba zalogowanych użytkowników

Liczba zalogowanych użytkowników
FukurouPL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
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.

Kopiuj
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

jurek1980
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3581
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ć.

FukurouPL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
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.

Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
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:

Kopiuj
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.

T0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 197
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.

FukurouPL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
0

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

Kopiuj
		// 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.

jurek1980
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3581
1

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

FukurouPL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
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.

jurek1980
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3581
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.