Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: System sesji
Forum PHP.pl > Forum > PHP
tiraeth
  1. <?php
  2. class Session
  3. {
  4.  var $session_id;
  5.  var $table = SESSIONS_TABLE;
  6.  
  7.  # Konstruktor, laczy z baza danych
  8.  function Session($config)
  9.  {
  10. $this->db = new sql_layer;
  11. $this->db->sql_open($config);
  12.  
  13. return true;
  14.  }
  15.  
  16.  # start sesji
  17.  function start()
  18.  {
  19. $this->garbage();
  20.  
  21. if($_GET['sid'] != '')
  22. {
  23.  $sessionid = $_GET['sid'];
  24. }
  25. else
  26. {
  27.  $sessionid = $this->session_id;
  28. }
  29.  
  30. if($sessionid)
  31. {
  32.  $sid = $sessionid;
  33.  $this->db->sql_query(&#092;"UPDATE \".$this->table.\" SET session_time=UNIX_TIMESTAMP() WHERE session_id='\".$sid.\"'\");
  34.  $this->session_id = ($sid != '') ? $sid : $this->session_id;
  35. }
  36. else
  37. {
  38.  $sid = md5(uniqid(rand(), true));
  39.  $this->db->sql_query(&#092;"INSERT INTO \".$this->table.\" VALUES('\".$sid.\"', UNIX_TIMESTAMP(), '')\") or die($this->db->sql_error());
  40.  $this->session_id = $sid;
  41. }
  42.  
  43. return true;
  44.  }
  45.  
  46.  # Dodajemy dane do sesji (jezeli $vars jest puste to tylko aktualizujemy \"session_time\")
  47.  function write($vars = '')
  48.  {
  49. if($vars == '')
  50. {
  51.  $this->db->sql_query(&#092;"UPDATE \".$this->table.\" SET session_time=UNIX_TIMESTAMP() WHERE session_id='\".$this->session_id.\"'\") or die($this->db->sql_error());
  52. }
  53. else
  54. {
  55.  $data = $this->read();
  56.  if(is_array($data))
  57.  {
  58. $info = array_merge($data, $vars);
  59.  }
  60.  else
  61.  {
  62. $info = $vars;
  63.  }
  64.  
  65.  $this->db->sql_query(&#092;"UPDATE \".$this->table.\" SET session_time=UNIX_TIMESTAMP() WHERE session_id='\".$this->session_id.\"'\") or die($this->db->sql_error());
  66.  $this->db->sql_query(&#092;"UPDATE \".$this->table.\" SET session_value='\".serialize($info).\"' WHERE session_id='\".$this->session_id.\"'\") or die($this->db->sql_error());
  67. }
  68.  
  69. return true;
  70.  }
  71.  
  72.  # Zamkniecie sesje uzytkownika (usuwamy sesje uzytkownika i wrzucamy pusta sesje o tym samym id)
  73.  function close()
  74.  {
  75. $this->db->sql_query(&#092;"DELETE FROM \".$this->table.\" WHERE session_id='\".$this->session_id.\"'\") or die($this->db->sql_error());
  76. $this->db->sql_query(&#092;"INSERT INTO \".$this->table.\" VALUES('\".$this->session_id.\"', UNIX_TIMESTAMP(), '')\") or die($this->db->sql_error());
  77. return true;
  78.  }
  79.  
  80.  # Odczytujemy wartosci sesji
  81.  function read()
  82.  {
  83. $this->db->sql_query(&#092;"SELECT session_value FROM \".$this->table.\" WHERE session_id='\".$this->session_id.\"' LIMIT 1\") or die($this->db->sql_error());
  84. $row = $this->db->sql_fetch();
  85. return unserialize($row['session_value']);
  86.  }
  87.  
  88.  # Wiadomo... wywolywane przy start()
  89.  function garbage()
  90.  {
  91. $time = strtotime('-72 hours');
  92. $this->db->sql_query(&#092;"DELETE FROM \".$this->table.\" WHERE session_time<'\".$time.\"'\") or die($this->db->sql_error());
  93.  }
  94. }
  95.  
  96. function append_sid($url)
  97. {
  98.  global $session;
  99.  if(strpos(&#092;"&\", $url) || strpos(\"?\", $url))
  100.  {
  101. $url.= '&sid='.$session->session_id;
  102.  }
  103.  else
  104.  {
  105. $url.= '?sid='.$session->session_id;
  106.  }
  107.  
  108.  return $url;
  109. }
  110.  
  111. # Startujemy sesje
  112. $session = new Session($config['sql']);
  113. $session->start();
  114. ?>


Na każdej stronie (prócz login.php) dodaję taki kod:
  1. <?php
  2. if($_GET['sid'] == &#092;"\")
  3. {
  4.  $adres = $_SERVER['PHP_SELF'];
  5.  
  6.  $i=0;
  7.  foreach($_GET as $key => $value)
  8.  {
  9. $adres.= ($i==0) ? '?' : '&';
  10. $adres.= $key.'='.$value;
  11. $i++;
  12.  }
  13.  header(&#092;"Location: \".append_sid($adres));
  14. }
  15.  
  16. $sessiondata = $session->read();
  17. $session->write();
  18. ?>

Czyli odczytuję dane sesji do zmiennej $sessiondata i aktualizuje obecny czas w sesji (session_time). Funkcja append_sid dodaje do adresu identyfikator sesji.

Loguję się za pomocą tego kodu:
  1. <?php
  2. # ... tutaj konfiguracja itp itd.
  3.  
  4.  
  5. include('config.php');
  6. include('includes/sql_layer.php');
  7. include('includes/constant.php');
  8. include('includes/session.php');
  9.  
  10. if($_GET['m'] == 'logout')
  11. {
  12.  $session->close();
  13.  header(&#092;"Location: index.php?sid=\".$session->session_id);
  14. }
  15. else
  16. {
  17.  if($sessiondata['logged_in'] == false)
  18.  {
  19. if($_POST['username']!='' && $_POST['password']!='')
  20. {
  21.  # loggin in user
  22.  $db->sql_query(&#092;"SELECT * FROM `\".USERS_TABLE.\"` WHERE username = '\".$_POST['username'].\"' AND user_password = '\".md5($_POST['password']).\"'\") or die($db->sql_error());
  23.  
  24.  if($row = $db->sql_fetch())
  25.  {
  26. $ses['logged_in'] = 1;
  27. $ses['user_id'] = $row['user_id'];
  28. $session->write($ses);
  29.  
  30. header(&#092;"Location: index.php?sid=\".$session->session_id);
  31.  }
  32.  else
  33.  {
  34. header(&#092;"Location: index.php?sid=\".$session->session_id);
  35.  }
  36. }
  37. else
  38. {
  39.  header(&#092;"Location: index.php?sid=\".$session->session_id);
  40. }
  41.  }
  42.  else
  43.  {
  44. header(&#092;"Location: index.php?sid=\".$session->session_id);
  45.  }
  46. }
  47.  
  48. ?>

Logowanie działa na takiej zasadzie: Zamiast usuwać sesję i tworzyć nową użytkownika zalogowanego, to poprostu uaktualniamy wartość sesji poprzez wywołanie $session->write($ses) na tym identyfikatorze.

Logowanie działa wporządku, nawigacja po stronie tak samo. Jedyna rzecz, która nie działa to wylogowywanie sad.gif Chcę aby było to na takiej samej zasadzie - pole session_value przy odpowiednim SID ustawiam jako puste ($session->close()) a następnie wracam na stronę główną z tym samym identyfikatorem ($session->session_id). Niestety po powrocie na stronę otrzymuję nowy identyfikator, przez co sesja użytkownika dalej jest w bazie.

Proszę o pomoc!!
nospor
próbuję i próbuję ale nic.
a co masz na myśli pisząc:
Cytat
Niestety po powrocie na stronę otrzymuję nowy identyfikator, przez co sesja użytkownika dalej jest w bazie.
Ale jak robisz close to kasujesz sesję z bazy i zakładasz nową o tym samym ID. Trochę to dziwne. NIe kumam. Pozatym nie lepiej zrobić UPDATE i wyczyscic tylko zbędne pola? Po co aż dwa zapytania?
tiraeth
1. wracam na stronę i mam już $_GET['sid'] i w warunkach (drugi kod) nie powinno utworzyć nowej sesji, tylko zaktualizować tą z SID pobranym z $_GET... jak robie F5 po zalogowaniu się, to normlanie aktualizuje czas...

2. Próbując zrobić UPDATE i ustawiając SET SESSION_VALUE='' wywala mi błąd mysql...
nospor
1) tyle to ja wiem. czytać umiem. Ino logiki nie kumam. Piszesz że wracasz na stronę głównę i masz inny identyfikator. A ty jak wracasz to nie podajesz w URL tego identyfikatora? Wszędzie podawaŁęs tylko teraz nie?

2) Skoro ci wywała błąd sql znaczy ze masz błąd sql tongue.gif To trzeba to poprawić a nie generować dwa inne zapytania. A gdzie optylny kod? Pokaz tego update to może coś poraadzimy winksmiley.jpg
tiraeth
1) header("Location: index.php?sid=".$session->session_id);
tak wracam smile.gif więc identyfikator jest przekazywany dalej

2)
  1. <?php
  2. $sql = &#092;"UPDATE \".$this->table.\" SET session_value='', session_time=UNIX_TIMESTAMP() WHERE session_id='\".$this->session_id.\"' LIMIT 1\";
  3. ?>

Coś w tym rodzaju...
nospor
1) hmm, dziwne. A po przejściu na tą stronę główną to dalej jest w url ten stary sid? Bo ty nowy sid nadajesz tylko w start() gdy nie ma starego ($_GET['sid'] nie istnieje) i tylko tam ma prawo się zmienić.
2) hmm, zapytanko wydaje się być ok jedynie ten limit jest zbędny

3) (nowe smile.gif ) robisz wiele zbędnych rzeczy w kodzie jak np.:
  1. <?php
  2.  
  3. if($sessionid)
  4. {
  5.  $sid = $sessionid;
  6. /...
  7.  $this->session_id = ($sid != '') ? $sid : $this->session_id;
  8. }
  9.  
  10. ?>
Skoro wszesdleś w waruenk to $sid bedzie mialo jakąś wartość i nie trzeba sprawdzać czy jest jakaś, a więc:
  1. <?php
  2.  
  3. if($sessionid)
  4. {
  5.  $sid = $sessionid;
  6. /...
  7.  $this->session_id = $sid;
  8. }
  9.  
  10. ?>
tiraeth
1. No właśnie po przejściu na stronę główną w adresie mam nowy ID, chyba coś nie tak z instrukcją ale to niemożliwe...

2. OK, podmieniłem, usunąłem LIMIT i działa.

3. Poprawiłem, faktycznie kombinowałem jak koń pod górę smile.gif

Nadal problem z 1!

Już wiem gdzie był błąd smile.gif append_sid dodawał wszędzie ?sid= smile.gif i dlatego nie przekazywało identyfikatora biggrin.gif
nospor
1) w close() nie zmieniasz identyfikatora. Może coś źle go potem przekazujesz. Możesz pokazać kod tam gdzie używasz close (wylogowanie)

2) No to popraw jeszcze to:
  1. <?php
  2.  
  3. $this->db->sql_query(&#092;"UPDATE \".$this->table.\" SET session_time=UNIX_TIMESTAMP() WHERE session_id='\".$this->session_id.\"'\") or die($this->db->sql_error());
  4.  $this->db->sql_query(&#092;"UPDATE \".$this->table.\" SET session_value='\".serialize($info).\"' WHERE session_id='\".$this->session_id.\"'\") or die($this->db->sql_error());
  5.  
  6. ?>
te dwa zapytania to mozna spokojnie jednym zrobić. przecież ta sama tabela , ten sam warunek tylko pola inne
tiraeth
Błąd rozwiązany smile.gif Info w poście powyżej (moim) smile.gif biggrin.gif Klasę udostępnie na forum Skrypty php... można zamknąć i usunąć..

@nospor: dzięki za wytrwałość przy moim problemie smile.gif
nospor
hihi, nie ma za co. flaszkę prześlij pocztą laugh.gif

tylko popraw nową 2)
tiraeth
@nosport sorki, że Cię tak ciągle męczę ale nie mogę sobie poradzić z dodaniem do tych sesji opcji zapamiętaj mnie. Wiem kiedy ustawić cookie ale nie potrafię dodać obsługę cookie do tej klasy smile.gif
nospor
hejka, weekendowa przerwa, ale już jestem biggrin.gif

Za bardzo nie rozumiem o jakiej obsłudze mówisz.
Improwizuję:
Jak gościu wciśnie zapamiętaj mnie, ustawiasz mu cookie z której wartością będzie sid (z racji że ty te sid w bazie trzymasz). Potem przy starcie sktyptu, gdy nie masz sid w url, zczytujesz czy jest Twoje cookie. Jak jest to je sczytujesz i patrzysz czy masz takie sid. Jak tak to oki, a jak nie to generujesz nowy sid jak dotej pory.

pozdro
tiraeth
Już sobie poradziłem z COOKIE'sami smile.gif Sprawdzam na stronie głównej czy jest cookie i czy nie ma session_id w adresie. Jeżeli zwraca mi TRUE to wtedy przeładowuję stronę, gdzie w GET przesyłam identyfikator sesji i już normalnie mogę pracować smile.gif

Dziękuję za pomoc smile.gif
nospor
hihi, rozumiemy się bez słów (podobna logika myślenia).

Aczkolwiek niepotrzebnie chyba przeładowujesz stronę gdy sid jest w ciastku. Skoro masz sid to Twój obiekt sesji ma wszystkie niezbędne dane i nie ma potrzeby go przeładowywać aby sczytał z url. Kolejne linki rób już z url z sid, ale tem jest niepotrzebny moim zdaniem.
tiraeth
A dokładneij to zczytywanie wygląda tak:

  1. <?php
  2. /***
  3.  * Sprawdzamy czy użytkownik ma sesję
  4.  */
  5. if($_GET['sid'] == &#092;"\")
  6. {
  7.    $adres = $_SERVER['PHP_SELF'];
  8.  
  9.    $i=0;
  10.    foreach($_GET as $key => $value)
  11.    {
  12.       $adres.= ($i==0) ? '?' : '&';
  13.       $adres.= $key.'='.$value;
  14.       $i++;
  15.    }
  16.    # $adres przetrzymuje nazwę \"tego\" pliku + wszystkie zmienne GET
  17.  
  18.    # Jezeli istnieje cookie...
  19.    if($_COOKIE['cms_sid'] != &#092;"\")
  20.    {
  21.       #...i taki identyfikator ma dane sesyjne
  22.       if($a = $session->read($_COOKIE['cms_sid']))
  23.       {
  24.          # usuwamy bieżącą sesję
  25.          $session->destroy();
  26.  
  27.          # ustawiamy SID z cookie
  28.          define('SID', $_COOKIE['cms_sid']);
  29.          unset($a);
  30.       }
  31.    }
  32. }
  33. ?>

Mam teraz taki kod, append_sid sprawdza czy istnieje session_id z klasy $session jeżeli tak to go dodaje a jeżeli nie (jest cookie) to ustawia SID z cookies'a
nospor
Uważam że ten kod (trochę zmieniony) powinieneś dodać do metody start() i nie przeładowywać strony i nie niszczyć sesji. Niepotrzebnie tutaj ciągle jest strona przeładowywana.
tiraeth
No to może podasz mi jak umieścić tą funkcję w metodzie start() ? Bo ja nie wiem biggrin.gif
nospor
myslalem o czymś takim (mogą być male literówki):
  1. <?php
  2.  
  3.  function start()
  4.  {
  5. $this->garbage();
  6.  
  7. if($_GET['sid'] != '')
  8. {
  9.  $sessionid = $_GET['sid'];
  10. }
  11. //!!!!!nowy kod!!!!!!
  12. else
  13.  if($_COOKIE['cms_sid'] != &#092;"\")
  14.  {
  15.  $sessionid = $_COOKIE['cms_sid'];
  16.  }
  17. //!!!!! koniec nowy kod!!!!!!
  18. else
  19. {
  20.  $sessionid = $this->session_id;
  21. }
  22.  
  23. if($sessionid)
  24. {
  25.  $sid = $sessionid;
  26.  $this->db->sql_query(&#092;"UPDATE \".$this->table.\" SET session_time=UNIX_TIMESTAMP() WHERE session_id='\".$sid.\"'\");
  27.  $this->session_id = ($sid != '') ? $sid : $this->session_id;
  28. }
  29. else
  30. {
  31.  $sid = md5(uniqid(rand(), true));
  32.  $this->db->sql_query(&#092;"INSERT INTO \".$this->table.\" VALUES('\".$sid.\"', UNIX_TIMESTAMP(), '')\") or die($this->db->sql_error());
  33.  $this->session_id = $sid;
  34. }
  35.  
  36. return true;
  37.  }
  38.  
  39. ?>
czy to nie będzie spelnialo Twojego oczekiwania?
tiraeth
No może być ciekawe smile.gif Jednak zastanawiam się jeszcze nad bezpieczeństwem ciastek. Nie wiem czy sprawdzać pochodzenie ciasta (identyfikacja przeglądarki) czy ustawiać dodatkowe z datą utworzenia COOKIE, żeby nikt nie podszył się pod innego użytkownika (nie utworzył sobie cookie). Co o tym sądzisz?
nospor
hmmm, no nie wiem. Możesz tworzyć cookie z sumą kontrolną dodatkowo jeszcze, która by była generowana np. z hasła. DOpiero jak to i sid bedą się zgadzały to wtedy będzie ok.
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.