Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> [MySQL][PHP] Wykrycie timeout sesji
Thompsoon
post 13.05.2015, 11:52:22
Post #1





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


Witam,

Mam problem.
Potrzebuje wykonać pewne operacje na bazie danych ale dopiero wtedy gdy użytkownik się wyloguje lub zostanie sam wylogowany automatycznie po timeout sesji.
Jeżeli chodzi o tę pierwszą wersje to poradziłem sobie bez problemu.
Niestety nie wiem jak wykryć, że dany użytkownik nie jest już aktywny i że wygasła sesja. Szukałem na różnych forach ale nie znalazłem niczego co pomogłoby mi rozwiązać problem.
Proszę o pomoc, nakierowanie.

Pozdrawiam
Go to the top of the page
+Quote Post
Pyton_000
post 13.05.2015, 12:00:32
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Robisz sesje na BD, okresowo sprawdzasz tabelę sesii pod kątem czasu ostatniej aktywności. Jeśli czas nieaktywności > ustalony czas sesii robisz sobie coś z userem, i wywalasz rekord z BD.
Go to the top of the page
+Quote Post
Thompsoon
post 13.05.2015, 15:16:30
Post #3





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


A nie ma takiej możlwiości żeby zrobić to z automatu, tak żeby nie sprawdzać samemu nieaktywności co jakiś czas ?
Jeżeli nie ma to czy można np. zrobić automat, który działa co jakiś określony czas?

Ten post edytował Thompsoon 13.05.2015, 15:16:55
Go to the top of the page
+Quote Post
Pyton_000
post 13.05.2015, 15:58:33
Post #4





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


cron
Go to the top of the page
+Quote Post
Thompsoon
post 13.05.2015, 16:05:51
Post #5





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


To jedyne rozwiązanie? Dopiero zaczynam przygodę z php i nie wiem czy będe w stanie to ugryźć
Go to the top of the page
+Quote Post
salfunglandyare
post 13.05.2015, 16:14:47
Post #6





Grupa: Zarejestrowani
Postów: 150
Pomógł: 31
Dołączył: 10.01.2007
Skąd: Bydgoszcz/Inowrocław

Ostrzeżenie: (0%)
-----


sesja na db - http://php.net/manual/en/function.session-...ave-handler.php
Zmiany w bazie przy usuwaniu rekordu sesji możesz wykonać przy pomocy triggerów before delete lub after delete. Za ich pomocą i sys_exec możesz wykonać nawet zewnętrzny skrypt/program bezpośrednio z mysql biggrin.gif np:
  1. DELIMITER //
  2.  
  3. CREATE TRIGGER po_usunieciu
  4. AFTER DELETE ON `Tabela`
  5. FOR EACH ROW
  6. BEGIN
  7. DECLARE zwrot int(10);
  8. DECLARE polecenie char(200);
  9. SET polecenie=CONCAT('/usr/bin/php /home/XXXX/skrypt.php ',OLD.id);
  10. SET zwrot = sys_exec(polecenie);
  11. END;
  12. //
  13. DELIMITER ;


//Edit: oczywiście zamiast sys_exec możesz wykonać jakiś SQL, informacje o starym rekordzie znajdują się w OLD

Ten post edytował salfunglandyare 13.05.2015, 16:22:39
Go to the top of the page
+Quote Post
rad11
post 13.05.2015, 16:50:40
Post #7





Grupa: Zarejestrowani
Postów: 1 270
Pomógł: 184
Dołączył: 7.10.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Zrob sobie przy uzytkowniku kolumne ostatni czas aktywnosci (oczywiscie aktywnosc musisz updatowac przy kazdym reloadzie), ustaw czas aktywnosci sesji np na 1 godzine jezeli uzytkownik ostatnia aktywnosc mial godzine temu to automatycznie sesja go wyloguje i bedziesz wiedziec ze jest nieaktywny rowniez w bazie danych.

Ten post edytował rad11 13.05.2015, 16:58:08
Go to the top of the page
+Quote Post
Thompsoon
post 13.05.2015, 17:00:42
Post #8





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


Cytat(rad11 @ 13.05.2015, 17:50:40 ) *
Zrob sobie przy uzytkowniku kolumne ostatni czas aktywnosci (oczywiscie aktywnosc musisz updatowac przy kazdym reloadzie), ustaw czas aktywnosci sesji np na 1 godzine jezeli uzytkownik w bazie ostatnia aktywnosc mial godzine temu to automatycznie sesja go wyloguje i bedziesz wiedziec ze jest nieaktywny.


Ten sposób chyba jest najbliższy temu co mam teraz.

Mam dwie kolumny: jedna pokazuje czy użytkownik jest aktywny a druga czas ostatniej aktywności. I to działa.
Tylko jak sprawdzić automatycznie czy użytkownik nie był aktywny przez np. godz i wysłać polecenie o wykonaniu określonych operacji na bazie gdy nie był aktywny?
Go to the top of the page
+Quote Post
rad11
post 13.05.2015, 17:08:04
Post #9





Grupa: Zarejestrowani
Postów: 1 270
Pomógł: 184
Dołączył: 7.10.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Musisz pobrac date ostatniej aktywnosci i porownac ja z aktualna. Jezeli roznica jest wieksza niz godzina tzn ze jest nieaktywny.
Go to the top of the page
+Quote Post
Thompsoon
post 13.05.2015, 17:17:31
Post #10





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


No tak, tylko to musiał bym zrobić nową funkcje i uruchamiać ją manualnie.

Idea jest taka:

1. Loguje się użytkownik
2. Robi jakieś dziwne rzeczy powodujące wpisy w bazie
3. Kończy pracę:
a. wylogowuję się -> odpalam funkcje, która czyści to czego nie potrzebuje - to zrobiłem
b. nie wylogowuje się -> sesja się zamyka po jakimś czasie automatycznie - i tutaj potrzebuje zrobić coś żeby wykrywało zamknięcie sesji i wykonywało funkcje takie jak przy wylogowaniu

Ten post edytował Thompsoon 13.05.2015, 17:18:07
Go to the top of the page
+Quote Post
rad11
post 13.05.2015, 17:19:07
Post #11





Grupa: Zarejestrowani
Postów: 1 270
Pomógł: 184
Dołączył: 7.10.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


No to Ci tlumacze masz do tego ostatnia aktywnosc. Jezeli bedziesz mial ustawiona sesje na godzine to na tej podstawie sprawdzasz ostatnia aktywnosc. Tylko jezeli nie chcesz tego robic manualnie bo z tego to wynika to musisz albo wykonywac ajaxem jakies operacje co jakis czas albo cronem.

Ten post edytował rad11 13.05.2015, 17:22:06
Go to the top of the page
+Quote Post
salfunglandyare
post 13.05.2015, 17:23:43
Post #12





Grupa: Zarejestrowani
Postów: 150
Pomógł: 31
Dołączył: 10.01.2007
Skąd: Bydgoszcz/Inowrocław

Ostrzeżenie: (0%)
-----


Albo mimo wszystko sesja w db i trigger na before/after delete biggrin.gif
Go to the top of the page
+Quote Post
rad11
post 13.05.2015, 17:27:01
Post #13





Grupa: Zarejestrowani
Postów: 1 270
Pomógł: 184
Dołączył: 7.10.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Lepiej aby chlopak zaczal od latwiejszego sposobu wedlug mnie haha.gif ale to juz jego wybor.
Go to the top of the page
+Quote Post
Thompsoon
post 13.05.2015, 17:51:50
Post #14





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


Cytat(salfunglandyare @ 13.05.2015, 18:23:43 ) *
Albo mimo wszystko sesja w db i trigger na before/after delete biggrin.gif


Czy w przypadku tego sposobu osiągnę to co zamierzam bez AJAXa i Crona?
Jeżeli tak to spróbuje się w to zagłębić chociaż na pierwszy rzut oka może być ciężko.

Manualne wykonywanie tej fukcji mnie niestety nie urządza. Operacje te muszą się wykonywać niemal niezwłocznie po zamknięciu sesji.
Go to the top of the page
+Quote Post
salfunglandyare
post 13.05.2015, 18:06:32
Post #15





Grupa: Zarejestrowani
Postów: 150
Pomógł: 31
Dołączył: 10.01.2007
Skąd: Bydgoszcz/Inowrocław

Ostrzeżenie: (0%)
-----


Generalnie tak:
- sesja zapisywana w bazie przez mechanizm PHP, gdy sesja ma timeout, PHP co jakiś czas sam sprawdza i wywołuje metodę usuwania (teoretycznie budując własny handler w tym miejscu też możesz się wpiąć). Uswanie powoduje usunięcie rekordu z bazy
- w bazie danych podczas usuniecia rekordu (lub rekordów) wywoływany jest trigger (before - przed usunieciem, after - po usunieciu),
- trigger może uruchomić SQL lub skrypt.
Problem jest w tym, aby dobrać się do wartości sesji, ale przy odrobinie wysiłku można dobrać się do wszystkich informacji, zawartość to zserializowana $_SESSION
Wszystko z automatu biggrin.gif

Ten post edytował salfunglandyare 13.05.2015, 18:07:18
Go to the top of the page
+Quote Post
Thompsoon
post 13.05.2015, 18:39:36
Post #16





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


Ok czyli wiem jak to ma działać ale jak się za to zabrać?
Pomoże ktoś? Deklaruje od razu, że jak uda się napisać taki skrypt to wrzucę go do sekcji "gotowe rozwiązania" żeby służył też innym.

Na początku musimy stworzyć bazę danych zapisujących sesje. Czy pola: Id, Timeout wystarczą?
Go to the top of the page
+Quote Post
salfunglandyare
post 13.05.2015, 18:45:41
Post #17





Grupa: Zarejestrowani
Postów: 150
Pomógł: 31
Dołączył: 10.01.2007
Skąd: Bydgoszcz/Inowrocław

Ostrzeżenie: (0%)
-----


http://php.net/manual/en/function.session-...ave-handler.php - tu w pierwszym komentarzu masz w sumie gotowe rozwiązanie na sesję w bazie smile.gif
Go to the top of the page
+Quote Post
Thompsoon
post 13.05.2015, 19:02:08
Post #18





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


Ok. Skopiuje do kodu swojej strony i zobaczę czy działa:)
Żartuje. Dzięki za pomoc.
Go to the top of the page
+Quote Post
Pyton_000
post 14.05.2015, 07:29:05
Post #19





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Skoro chcesz wykonać operacje po wylogowaniu i zakończeniu sesji to czy nie lepiej czyścić przed zalogowaniem? (O ile dane które są czyszczone nie są powiązane z niczym poza samym uzytkownikiem)
Go to the top of the page
+Quote Post
Thompsoon
post 14.05.2015, 18:34:23
Post #20





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 21.03.2015

Ostrzeżenie: (0%)
-----


Ale jeżeli ktoś się już nie zaloguje? Coś tam podłubie, niewyloguje się i zamknie przeglądarke
Chyba, że przed jakimolwiek zalogowaniem miałby sprawdzać czy czasy aktywnosci w bazie a nie w przypadku konkretnego usera.
Rozwiązanie nieidealne ale zawsze coś.

W międzyczasie przygotowałem kod. Tzn przerobiłem ten http://php.net/manual/en/function.session-...ave-handler.php

  1.  
  2. class session
  3. {
  4. // session-lifetime
  5. var $lifeTime;
  6. // mysql-handle
  7. var $db_connect;
  8.  
  9. function open($savePath, $sessName)
  10. {
  11. // get session-lifetime
  12. $this->lifeTime = get_cfg_var("session.gc_maxlifetime");
  13. // open database-connection
  14. require "db_connection.php";
  15. // return success
  16. $this->db_connect = $db_connect;
  17.  
  18. return true;
  19. }
  20.  
  21. function close()
  22. {
  23. $this->gc(ini_get('session.gc_maxlifetime'));
  24. // close database-connection
  25. return mysqli_close($this->db_connect);
  26. }
  27.  
  28. function read($sessID)
  29. {
  30. // fetch session-data
  31. $query = "SELECT SessionData AS d FROM Sessions WHERE Id = '$sessID' AND SessionExpires > ".time();
  32.  
  33. $res = mysqli_query($this->db_connect, $query);
  34.  
  35. // return data or an empty string at failure
  36. if($row = mysqli_fetch_assoc($res))
  37. return $row['d'];
  38. return "";
  39. }
  40.  
  41. function write($sessID,$sessData)
  42. {
  43. // new session-expire-time
  44. $newExp = time() + $this->lifeTime;
  45. // is a session with this id in the database?
  46.  
  47. $query = "SELECT * FROM Sessions WHERE Id = '$sessID' ";
  48.  
  49. $res = mysqli_query($this->db_connect, $query);
  50.  
  51. // if yes,
  52. if(mysqli_num_rows($res)) {
  53. // ...update session-data
  54.  
  55. $query = "UPDATE Sessions SET SessionExpires = '$newExp', SessionData = '$sessData' WHERE Id = '$sessID' ";
  56.  
  57. mysqli_query($this->db_connect, $query);
  58.  
  59. // if something happened, return true
  60. if(mysqli_affected_rows($this->db_connect))
  61. return true;
  62. } else {
  63. // if no session-data was found,
  64. // create a new row
  65. $query2 = "INSERT INTO Sessions (Id, SessionExpires, SessionData)
  66. VALUES('$sessID', '$newExp', '$sessData')";
  67.  
  68. mysqli_query($this->db_connect, $query2);
  69.  
  70. // if row was created, return true
  71. if(mysqli_affected_rows($this->db_connect))
  72. return true;
  73. }
  74. // an unknown error occured
  75. return false;
  76. }
  77.  
  78. function destroy($sessID)
  79. {
  80. // delete session-data
  81. $query = "DELETE FROM Sessions WHERE Id = '$sessID' ";
  82.  
  83. mysqli_query($this->db_connect, $query);
  84.  
  85. // if session was deleted, return true,
  86. if(mysql_affected_rows($this->db_connect))
  87. return true;
  88. // ...else return false
  89. return false;
  90. }
  91.  
  92. function gc($sessMaxLifeTime)
  93. {
  94. // delete old sessions
  95. $query = "DELETE FROM Sessions WHERE SessionExpires < ".time();
  96.  
  97. mysqli_query($this->db_connect, $query);
  98.  
  99. // return affected rows
  100. return mysql_affected_rows($this->db_connect);
  101.  
  102. return true;
  103. }
  104.  
  105. }
  106.  
  107. $session = new session();
  108. session_set_save_handler(array(&$session,"open"),
  109. array(&$session,"close"),
  110. array(&$session,"read"),
  111. array(&$session,"write"),
  112. array(&$session,"destroy"),
  113. array(&$session,"gc"));
  114.  
  115.  
  116.  


Ale chyba nie działa tak jakbym chciał.
Zapisuje w polu 'Id' nazwę sesji, aktualizuje 'SessionExpires' w przypadku przeładowania strony ale w momenie gdy np. otworzę stronę na dwóch różnych przeglądarkach to mam tylko jeden wpis w bazie. Tak jakby się zastępował, a przecież gdy nie znajdzie 'Id' sesji to powienien tworzyć nowy.
I widzę też że sesja nie usuwa się z bazy danych.
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.07.2025 - 08:35