Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php]Wykonanie skryptu przy zamknięciu przeglądarki
Forum PHP.pl > Forum > PHP
Hannon
Przy zamknięciu przeglądarki zamykana jest sesja - ok.
Chciałem zapisać pare informacji przy zamknięciu przeglądarki.
Ale ni cholery niewiem jak to zrobić.
Przemknęło mi przez myśl postawienie crona który będzie odpalał skrypt który będzie sprawdzał czy sesja jest zamknięta a jeśli tak to sru zapis ale to sie mija z celem bo godziny nie będą prawidłowe a zmienne juz nie będą istnieć..
Brakuje mi jakiegoś spustu który wykona to.
Zastanawiałem się nad wykorzystaniem javascriptu onClose="x"
ale to chyba też nie zadziała bo jak to wrzuce to przecież nie wykona mi skryptu bo to po stronie przeglądarki a nie serwera.

Ma ktoś jakieś pomysły ?
webdice
Mi do głowy przychodzi na razie jeden nie zbyt elegancki pomysł. Po zamknięciu przeglądarki wyskakuje POP-UP otwierający plik PHP który usuwa sesję, a następnie sie sam zamyka. Nie wiem tylko jak jest z sesjami w POP-UP'ach.
sniezny_wilk
A jakie informacje chcesz przekazać ? Może da się to jakoś obejść

@webdicepl - z tego co wiem pop-up będzie miał taki sam dostęp do sesji jak i strona z jakiej jest wywoływany.

Ale co w przypadku, gdy user po prostu wyłączy komputer nie zamykając przeglądarki ? Czy to są jakieś ważne dane ?
webdice
Był kiedyś o tym temat na forum, nie ma dobrego sposobu na zrobienie czegoś takiego.

Cytat(sniezny_wilk @ 24.12.2007, 15:50:40 ) *
@webdicepl - z tego co wiem pop-up będzie miał taki sam dostęp do sesji jak i strona z jakiej jest wywoływany.


Nie korzystam z POP-UP'ów, ale z tego co pamiętam w IE6 miał chyba inną sesje.
Boski
można robić backupa sesji co x sekund lub przy odświeżeniu strony a najlepiej żeby w sesji nie trzymać ważnych informacji
Hannon
Dopisanie do pliku txt że dany użytkownik o danym ip zamknął przeglądarkę o danej godzinie nie wylogowując się.
Inwigilacja administracji rox.
Czyli nikt niema jakiegoś pomysłu ?
calfik
no moze a ktos mogl by mi  podpowiedziec jak przy zamykaniu przegladarki dokonac zmiany w zmiennych i  wyslac te zmienne na server questionmark.gif
.chudy.
Może zrób mniej więcej tak. Przy logowaniu się usera wprowadz do bazy date logowania (oczywiście z czasem winksmiley.jpg ) i przy POPRAWNYM wyjściu ze strony (logout) wprowadz date kiedy sie wylogował, następnie przy ponownym logowaniu będzie sprawdzał czy ostatnio user się wylogował. Albo używając ajaxu sprawdzaj czy user jeszcze siedzi na stronie.
calfik
a jakies informacje co w tym ajaxie trzeba napisac i jak to napisac jakies przyklady bo juz nie jedna osoba mi mowila ze tak ale ja nie mam zielonego pojecia
czachor
Może coś z tym? Obsługa połączeń i connection_aborted().
Hannon
No... ale wyjście ze strony != logout.
Wyjście ze strony to zamknięcie okna z stroną.
Wylogowanie to zakończenie sesji.

Z zakończeniem sesji moge sobie poradzić, ale jak wykonać skrypt przy zamykaniu/po zamknięciu.
calfik
Hannon a mogl bys powiedziec jak to zrobiles bo mam problem z tym zeby to wymyslec jak to zrobic przykladowy jakis kod mogl bys mi podac albo na maila calfik@gmail.com
Babcia@Stefa
Cytat(Hannon @ 25.12.2007, 23:48:07 ) *
No... ale wyjście ze strony != logout.
Wyjście ze strony to zamknięcie okna z stroną.
Wylogowanie to zakończenie sesji.

Z zakończeniem sesji moge sobie poradzić, ale jak wykonać skrypt przy zamykaniu/po zamknięciu.


To proste.
Wystarczy wykorzystać Ajax.
  1. <script type="text/javascript"> // pierwsza część kodu var ObiektXMLHttp = false;
  2. if (window.XMLHttpRequest)
  3. {
  4. ObiektXMLHttp = new XMLHttpRequest(); }
  5. else if (window.ActiveXObject)
  6. {
  7. ObiektXMLHttp = new ActiveXObject("Microsoft.XMLHTTP"); }
  8.  
  9. // druga część kodu
  10. function getData(zrodlo) {
  11. if(ObiektXMLHttp)
  12. {
  13. ObiektXMLHttp.open("GET", zrodlo);
  14.  
  15. ObiektXMLHttp.onreadystatechange = function()
  16. {
  17. }
  18. // trzecia część kodu
  19. ObiektXMLHttp.send(null); } } </script>


W kodzie html:

  1. <body onunload="getData('sesje.php');">


Sesje.php
Kod
<?php
include('controller.php');
$session = new SESSION();
$session -> destroyall();
?>


@edit
Źródło ajax:
http://webmade.org/porady/ajax.php

Dziękuję, Babcia@Stefa
k0b3
ten ajax za pomocą jQuery dało by się zrobić?
Kilka funkcji użyłem i szkoda gdybym pisał ten powyższy skrypt jak mam takiego frameworka.
bim2
No wywołaj to tak samo jak ajax w jquery ;p
onunload="$('#div').load('session.php');"

czy jak tam to robisz
krowal
@Babcia@Stefa
Twoje rozwiązanie jest ok, ale... ssie winksmiley.jpg jeśli ustawisz unload na body to reakcja będzie nawet wtedy gdy klikniesz jakiegoś linka lub odświeżysz stronę. Poza tym gdzieś czytałem, że chyba nie działa dobrze w IE6 (nie sprawdzałem).
Ja bym to zrobił w taki sposób, że wysyłałbym ajaxem np. co 5 min informację z sessionid o aktywności użytkownika i jeśli sesja nie wygasła to zapisywałbym czas ostatniej aktywności. Jeśli użytkownik wylogowałby się poprawnie to ustawiłbym w bazie przy jego sesji jakiś znacznik informujący o poprawnym wylogowaniu np. logged_out = 1 (domyślnie ustawiane na 0). Później jakiś administrator wchodząc na stronę otrzymywałby info o wszystkich użytkownikach dla których logged_out == 0 i czas ostatniej aktywności był wcześniejszy niż NOW() - 5min

W ten sposób możesz określić czas wyjścia bez wylogowania z dokładnością do 5 min.

Edit: @chudy, nie zauważyłem, że mniej więcej to samo już napisałeś smile.gif
LBO
JA bym się najpierw zastanowił, czy nie można tego obejść. Język PHP nie ma dostępu do przeglądarki przecież i wszelkie próby emulowania tego, czy to przez pop-upy, czy AJAX są zawodne (czyt. nie można na nich polegać).
Podsumowując - nigdy nie będziesz pewny, że użytkownik zamknął przeglądarkę. I zamiast siedzieć nad obejściem tego, pomyśl nad innym rozwiązaniem.

edit: zastanawia mnie co to za informacje chcesz zapisywać, przy zamknięciu? Bo tak czy siak, te informacje są na pewno dostępne przy każdym requeście, prawda?
Użytkownik wchodzi na stronę zapisujesz te dane w bazie i w sesji, przy każdym następnym requeście sprawdzasz różnice - jeżeli takie istnieją dopisujesz/nadpisujesz je do bazy. Rozwiązane.
k0b3
Cytat(LBO @ 21.08.2008, 09:33:24 ) *
Użytkownik wchodzi na stronę zapisujesz te dane w bazie i w sesji, przy każdym następnym requeście sprawdzasz różnice - jeżeli takie istnieją dopisujesz/nadpisujesz je do bazy. Rozwiązane.


jak za pomocą php sprawdzić czy dana sesja zostałą zakończona?
Jak rozumiem, zakończenie danej sesji jest przy zamknięciu przeglądarki.

informacje o sesji przetrzymuje w bazie sql: session_id() oraz id użytkownika. Gdy jest -1 to znaczy ze jest to gość, gdy przybiera numery od 1 oznacza ze ktos z id1 jest zalogowany.

da sie to jakoś wykorzystać?
LBO
Nie wiesz tego i się nie dowiesz... niestety.
k0b3
no to moze odwrotnie.

Czy da sie sprawdzić aktywność danej sesji? taki ping do użytkownika ;P jeśli nie ma odpowiedzi coś tam się robi.


BTW, skrobnijcie kodem na to poniższe rozwiązanie.. Ajaxem da sie sprawdzić aktywnośc użytkownika wg session_id i czy ta sesja nie wygasła?
Cytat(krowal @ 21.08.2008, 07:18:08 ) *
Ja bym to zrobił w taki sposób, że wysyłałbym ajaxem np. co 5 min informację z sessionid o aktywności użytkownika i jeśli sesja nie wygasła to zapisywałbym czas ostatniej aktywności.
LBO
Naprawdę chcesz polegać na AJAXie?

Napisz co dokładnie chcesz zapisać po zamknięciu przeglądarki i po co ma to Tobie służyć później.
franki01
Ja bym zastanawiał się na trochę innym rozwiązaniem. Zakładam, że użytkownicy są trzymani w bazie danych i mają takie pola jak
Kod
UserLogin - wiadomo
UserPassword - wiadomo
UserLogged - wartość 1 gdy jest zalogowany, a 0 gdy nie (gdy wciśnie Logout wartość podmienia się na 0, a przy logowaniu na 1)
UserLastRefreshed - time() ostatniego odświeżenia strony przez użytkownika
no i do tego oczywiście reszta pól


Teraz gdy użytkownik ostatni raz odświeżył stronę, po czym wyszedł bez wylogowania, pole UserLogged ma wartość 1.
Przy następnym logowaniu tego użytkownika można sprawdzić czy wylogował się poprzednim razem, co da podobny efekt do zamierzonego..

  1. <?php
  2. // Fragment kodu przy logowaniu na konto
  3. $query = "SELECT * FROM `users` WHERE `UserLogin`='{$_POST['login']}' AND `UserPassword`='".md5($_POST['password']."'";
  4. $result = mysql_query($query);
  5.  
  6. if(mysql_num_rows($result) == 1)
  7. {
  8. $user = mysql_fetch_assoc($result);
  9. if($user['UserLogged'] == 1 && $user['UserLastRefreshed'] > 0) // właśnie ten kawałek kodu
  10. {
  11. // blok zapisujący dane do pliku używający $user['UserLastRefreshed'] jako orientacyjnego czasu zamknięcia przeglądarki
  12. }
  13. }
  14. ?>


Fakt, że nie będzie działało dokładnie, jakby sobie się tego życzyło, ale w jakimś stopniu spełnia swoje zadanie.
k0b3
Z użytkownikami zalogowanymi nie mam problemu.
Robie CMSa gdzie statystki pokazują aktywnych użytkowników. Oprócz tych zalogowanych są również goście.
mam dwie bazy między którymi zawiązane są interakcje: users oraz session.

w sessions jak juz wspomaniałem w poprzednim poście mam dwie kolumny:
session_id oraz user_id (domyślnie:-1)
-1 odpowiada użytkownikom anonimowym (niezalogowanym), czyli goście.
gdy ktoś się loguje następuje UPDATE bazy session i zmienia się to -1 w odpowiedniej sesji na id użytkownika pobrane z bazy users.

Liczba gości pobierana jest za pomocą num_rows:
  1. <?php
  2. $sql= @mysql_query("SELECT * FROM session WHERE session_user_id='-1'");
  3. $num_rows = mysql_num_rows($sql);
  4. ?>

wracając troche: Gdy ktoś wchodzi na stronę tworzy się nowa sesja. Przy zamknięciu i ponownym uruchomieniu strony znowu się tworzy nowa sesja, przez co te -1 w sesji gromadzą się i liczba gości ciągle rośnie.

Teraz wracając do Twojego pytania.
NIe musi to być w AJAXIE (nie przepadam za tym utrudnianiem sobie życia), ale porblem polega na tym, żeby sprawdzić czy dana sesja się zakończyła, czy ktoś zamkną tą przeglądarkę itp. Poprostu jakoś to sprawdzić. Wtedy usuwam sobie rekord w tabeli session pod względem nieaktywnego id sesji.

Mam nadzieje ze jasno wyjaśniłem ;P

dodam jeszcze, że ciastko sessji jest tez ustawione na określony czas.
  1. <?php
  2. ?>

Gdy się zakończy i usunie, sesje w bazie zostaje i to -1(gość) również.
franki01
Chyba nie do końca zrozumiałeś założenia mojego skryptu smile.gif Przeczytaj jeszcze raz. Chodzi o sprawdzenie przy kolejnym logowaniu, czy przy poprzednim użytkownik się wylogował, a nie czy aktualnie jest online (oO).
LBO
A ja napisałem, że np Firefox może trzymać sesję w nieskończoność.
Zrezygnuj z tego - nie możesz pozwolić, żeby system statystyk polegał na JavaScripcie.
Zrób tak jak robi znakomita większość aplikacji - do statystyk bierz tylko czas ostatniej akcji.
k0b3
Cytat(LBO @ 21.08.2008, 11:33:16 ) *
czas ostatniej akcji.

myślałem o tym. Ma to mniej więcej polegać na tym, że spradza aktywnośc użytkownika. Dobrze mysle?

Do session dodam sobie dwie kolumny (session_start i session_time)
przy utworzeniu nowej sesji doda mi do kolumny oprócz session_id dokładny czas powstania i czas akcji użytkownika tej sesji.

Przy wchodzeniu lub odświerzaniu strony ma mi aktualizować tabele o session_time wg session_id.

i później co? gdy np czas session_time jest mniejszy od teraźniejszego czasu o np 5 minut usuwa mi użytkownika tamtego czasu.

hm? tak to ma działać?
LBO
Tak, możesz jedynie szacować ten czas.
Usuwasz jakimś skryptem odpalanym cyklicznie np. spod CRONa, albo podpiąć pod sesje PHP session_set_save_handler" title="Zobacz w manualu PHP" target="_manual i zostawić to wewnętrznemu garbage-collectorowi.

edit:
i nie kombinuj z tyloma zmiennymi, dodaj zwyczajnie kolumnę last_action_time do tabeli z użytkownikami, to wszystko co będzie Tobie potrzebne.
Przy każdym requeście (odświeżeniu) aktualizuj tą kolumnę na time" title="Zobacz w manualu PHP" target="_manual i tyle. Potem możesz robić z tym co zechcesz - m.in. w przybliżeniu stwierdzać, czy użytkownik jest jeszcze na stronie (czy jest online)
kemot
Z tego co zrozumiałem chcesz zapisać czas kiedy dany użytkownik się wylogował. Myśle, że rozwiazanie może być banalnie proste choć nie sprawdzałem tego. W odpowiednią instrukcje do wylogowanie należałoby wpisać:


  1. <?php
  2.  
  3. //w momencie wykonywania instrukcji pobierany jest aktualny czas do zmiennej $data
  4.  
  5. $data = date("Y-m-d H:i:s");
  6.  
  7. $query = "UPDATE nazwatabeli SET last_action='".$data."' WHERE id='".$id."';"; //następnie przekazywana do bazy danych do kolumny last_action
  8. $wynik = mysql_query ($query);
  9. session_destroy();  //po wykonaniu zapytania kończysz sesje
  10.  
  11.  
  12. header ("location: logout.php");  //strona na którą przeniesie po zakończeniu sesji
  13.  
  14. ?>
LBO
@kemot, źle zrozumiałeś - to to jest banał. Chodziło o zamknięcie sesji, którego nota bene nie da się wykryć, bez odnoszenia się do zawodnego JavaScriptu.
franki01
Nie w momencie, kiedy się wylogował, lecz kiedy zamknął przeglądarkę.

Masz już chyba dość przykładów. Jest z czego wybierać.
k0b3
@lbo lub @franki01 skrobnijcie jakiś kod dotyczacy sprawdzenia tego czasu. Chciałem sobie porównać. Nie jestem doświadczony w php.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.