Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MySQLi] Sesje w bazie danych
Forum PHP.pl > Forum > PHP
zdun
Dzien dobry. Mam pewien problem poniewaz pierwszy raz sie za to zabrałem i nie wiem jak ise do tego dobrac. Poczytalem troche na necie i zrobilem przyklad.

Ustawienie tabeli 'sessions' w bazie 'sesje_testy'

  1. $addtable = mysqli_query($conn, "CREATE TABLE sessions(id varchar(32) COLLATE utf8_unicode_ci NOT NULL, access int(10) unsigned, data text COLLATE utf8_unicode_ci, PRIMARY KEY (id))");


Skrypt 'handler.inc'

  1. <?php
  2. '_close',
  3. '_read',
  4. '_write',
  5. '_destroy',
  6. '_clean');
  7.  
  8.  
  9.  
  10.  
  11. function _open()
  12. {
  13.  
  14. global $conn;
  15.  
  16. $conn = mysqli_connect('localhost', 'root@localhost', 'pwd');
  17.  
  18. if($conn) {
  19.  
  20. return mysqli_select_db($conn, "sesje_testy");
  21.  
  22. }
  23.  
  24. return FALSE;
  25.  
  26.  
  27. }
  28.  
  29.  
  30.  
  31. function _read($id)
  32. {
  33. global $conn;
  34.  
  35. $id = mysqli_real_escape_string($conn, $id);
  36.  
  37. $sql = "SELECT data
  38. FROM sessions
  39. WHERE id = '$id'";
  40.  
  41. if($result = mysqli_query($conn, $sql))
  42. {
  43.  
  44. if(mysqli_num_rows($result) > 0)
  45. {
  46.  
  47. $ro = mysqli_fetch_assoc($result);
  48.  
  49. return $ro['data'];
  50.  
  51. }
  52.  
  53. }
  54.  
  55.  
  56.  
  57. return '';
  58. }
  59.  
  60.  
  61.  
  62.  
  63.  
  64. function _write($id, $data)
  65. {
  66.  
  67. global $conn;
  68.  
  69. $access = time();
  70.  
  71. $id = mysqli_real_escape_string($conn, $id);
  72. $access = mysqli_real_escape_string($conn, $access);
  73. $data = mysqli_real_escape_string($conn, $data);
  74.  
  75. $sql = "REPLACE
  76. INTO sessions
  77. VALUES ('$id', '$access', '$data')";
  78.  
  79. return mysqli_query($conn, $sql);
  80.  
  81. }
  82.  
  83.  
  84. function _clean($max)
  85. {
  86. global $conn;
  87.  
  88. $old = time() - $max;
  89. $old = mysqli_real_escape_string($conn, $old);
  90.  
  91. $sql = "DELETE
  92. FROM sesions
  93. WHERE access < '$old'";
  94.  
  95. return mysqli_query($conn, $sql);
  96. }
  97.  
  98.  
  99.  
  100. function _destroy($id)
  101. {
  102. global $conn;
  103.  
  104. $id = mysqli_real_escape_string($conn, $id);
  105.  
  106. $sql = "DELETE
  107. FROM sesions
  108. WHERE id = '$id'";
  109.  
  110. return mysqli_query($conn, $sql);
  111. }
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118. function _close()
  119. {
  120. global $conn;
  121.  
  122. return mysqli_close($conn);
  123. }
  124.  
  125.  
  126. ?>



Plik 'set.php' do ustawienia sesji.

  1. <?php
  2. include('handler.inc');
  3.  
  4. $_SESSION['test'] = '5555';
  5.  
  6. ?>



Plik wywolujacy sesje.

  1. <?php include('session_save_handler.inc');
  2. ?>

Są tam zmienne: $id, $access i $data
I teraz zaczynają się schody bo...
nie wiem jak mam usunac:

1. sesje poprzez te funkcje _destroy(). Ta funkcja ma argument $id ale jak wpisuje (zamiast tego $id) session_id() czyli _destroy(session_id()) to nic sie nie dzieje.
W bazie jest przechowywane ID sesji, TIMESTAMP i dane sesji (nazwa i wartosc)

2. Nie wiem tez jak usunac sesje jesli minie czas: funkcja _clean($max) i czym jest teraz $max questionmark.gif?

W tym momencie sa w jednym pliku wszystkie funkcje ale czy tak to ma byc ? bo troche bez sensu jest skoro f. _write() ciagle mi nadpisuje TIMESTAMPA i jak ma sie wtedy wykonac f. _clean() questionmark.gif?

Chyba ze to mam porozdzielac na rozne pliki czy gdzie chce to poprostu pisze taka funkcje. Juz sam nie wiem
Pyton_000
Poczytaj sobie dokumentację: https://www.php.net/session_set_save_handler

Wskazówka. Utwórz sobię klasę SessionHandlera implementującą interfejs tam podany (czytaj również komentarze w manualu bo zawierają mnuuustwo ciekawych rzeczy) i użyj.

$max oznacza czas życia sesji. Czyli musisz time() - $max > $session_save_time i masz wynik sesjia przeterminowana.
zdun
Tak jak napisalem wczesniej. Wywolujac te funkcje _clean() z argumentem tj. _clean(120); // 120sekund nic sie nie robi. Jest tam zmienna $old ktora zawiera wynik time() - $max czyli aktualny czas - 120sekund. I teraz jest warunek z bazy ze jesli access jest mniejszy od $old to ma usunac wszystko co jest mniejsze. Tylko ze wczesniej jest funkcja _write() ktora zawiera polecenie REPLACE i za kazdym razem nadpisuje timestamp (ten sam ktory zostaje potem sprawdzany w tej f. _clean() )
To malo. Probowalem usunac WSZYSTKO z tej tabeli wywolujac funkcje _clear() bez zadnego argumentu i tez nic.
O co chodzi?

Nikt nie wie??

Przyklad pochodzi z tej strony ktora bardzo duzo ludzi poleca.

http://shiflett.org/articles/storing-sessions-in-a-database

Wszystko dziala procz f. _clean()
Zaraz zeświruje
Pyton_000
Ale po co chcesz to ręcznie wywoływać? PHP Automatem odpala sobie tą funkcję. Ty jedynie sprawdź czy samo zapytanie jest dobre.
zdun
No jesli chce ustawic sesje to robi to automatycznie ale musze wywolywac recznie w przypadku kiedy chce:
1. Usunac sesje.
2. Usunac rekord z bazy. I to nie dziala.Nawet jak nie robie tego "ręcznie" to i tak nie dziala bo co odswieżenie sprawdzam tabele i ciagle rekord istnieje.

Pierwsze dziala kiedy wywolam f. _destroy() z argumentem session_id() lub poprostu $id czyli:
_dstroy($id);

Mozesz mi powiedziec jak powinna wygladac ta funkcja _clean() ? Tam jest ta zmienna $max chodzi mi o to wlasnie.
Kiedy zamiast $max dam liczbe to wywala mi blad ze parser oczekuje zmiennej. No to wtedy w innym pliku includuje ten plik z tymi funkcjami, daje session_start() i wywoluje funkcje poprzez _clean('120'); i wtedy nie mam jiz bledu ale nic tez sie nie dzieje.

Stary, nie czaje tego bo zalozmy ze:
wartosc time() to "1000" czyli ten "tysiąc"" zapisuje sie do bazy w f. _write()
W tym samym momencie dziala f. _clean() i tam bedzie tak:

$old = "1000" - $max // $max czyli 120 sekund
Czyli wartosc zmiennej $old to 880
I dalej zapytanie do bazy ze :
Usun jesli "access" jesli jest mniejsze od $old
Problem w tym ze nigdy mniejsze nie bedzie bo access to 1000 a $old to 880

Te 1000 to tylko umowne ale nie wazne czy to bedzie timestamp ktory co sekunde sie zwieksza czy to bedzie stala wsrtosc bo to wystepuje sarowno w f. _write() jak i w f. _clean() - ta sama wartosc w tym samym czasie.

Ok. Wiec czemu by nie zamienic operatora na odwrot wtedy na logike powinno sie wykonac zapytanie. Niestety nie wykonuje sie.
Ten przyklad caly pochodzi z tamtej strony ktora podalem. Raczej nikt tam blefu nie popelnil. Wiec gdzie on jest tutaj skoro wszystko powinno dzialac.
Musze wywolywac recznie _clean($arg); bo musze przekazac wartosc ale nawet jak to zrobie w srodku funkcji to tez nie dziala. Wszystko inne tak.
redeemer
Cytat(zdun @ 30.03.2019, 09:52:04 ) *
....
Ten przyklad caly pochodzi z tamtej strony ktora podalem. Raczej nikt tam blefu nie popelnil. Wiec gdzie on jest tutaj skoro wszystko powinno dzialac.

Ten artykuł ma 15 lat!
zdun
Teraz pytanie ogolne.

Jest wogole sens tak kombinowac z sesjami zeby je zapisywac w bazie ? Bo przeciez wazniejsze jest cookie sesji nie sama sesja ktora notabene jest ustawniana w przegladarce.
Moze lepiej skupic sie na samym ciachu zamiast kombinowac z sesjami.

Co o tym myslisz.

Cytat(redeemer @ 30.03.2019, 13:23:33 ) *
Ten artykuł ma 15 lat!


Owszem ale przyklad zostal przerobiony z mysql na mysqli.

redeemer
Jeżeli koniecznie z jakiegoś powodu nie chcesz zapisywać sesji na dysku (standardowe ustawienie php), to lepiej do tego nadają się memcached albo redis.
Wystarczy zmienić odpowiednie ustawienia:

Kod
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

Rzuć też okiem na resztę opcji dotyczących sesji:

https://www.php.net/manual/en/session.configuration.php
zdun
Cytat(redeemer @ 30.03.2019, 13:40:25 ) *
Jeżeli koniecznie z jakiegoś powodu nie chcesz zapisywać sesji na dysku (standardowe ustawienie php), to lepiej do tego nadają się memcached albo redis.
Wystarczy zmienić odpowiednie ustawienia:

Kod
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

Rzuć też okiem na resztę opcji dotyczących sesji:

https://www.php.net/manual/en/session.configuration.php


Ogolnie to nie wiem tak konkretnie czy jest sens trzymania sesji w bazie. Jest sens questionmark.gif

Szukam i szukam i znalazłem jeszcze cos takiego i to sprawdze:

http://www.hackingwithphp.com/10/3/7/files-vs-databases

Po prostu szukam rozwiazania ktore zapewni mi maks bezpieczenstwa. Ale czy to rozwiaze mi moj problem questionmark.gif
Nie wiem czy olac to wywolywac sesje zwyczajnie uwazajac na ciastko sesyjne. Aktualizowac id sesji i samą sesje...
viking
Ja bym jeszcze to poczytał https://igotaprinter.com/blog/database-back...ken-in-php.html
zdun
Cytat(viking @ 30.03.2019, 14:06:24 ) *
Chodzi mi o konkretną odpowiedz.
tak lub nie.
Ja na Tobie nic nie wymuszam. Chcesz to napisz ale konkretnie
viking
W dokumentacji masz kilka przykładów gotowych klas. Na githubie zapewne jeszcze więcej projektów. Do rad zastosowania interface i tak się nie stosujesz a nawet jak to zacznie działać będzie i tak złe z powodów wymienionych w powyższym artykule. Więc jakiej odpowiedzi oczekujesz?

Gotowe https://github.com/JamieCressey/PHP-MySQL-S...sionHandler.php
Pyton_000
To ja odpowiem. Jeśli nie wiesz po co Ci to to odpowiedź jest NIE
zdun
Cytat(viking @ 30.03.2019, 15:45:21 ) *
W dokumentacji masz kilka przykładów gotowych klas. Na githubie zapewne jeszcze więcej projektów. Do rad zastosowania interface i tak się nie stosujesz a nawet jak to zacznie działać będzie i tak złe z powodów wymienionych w powyższym artykule. Więc jakiej odpowiedzi oczekujesz?

Gotowe https://github.com/JamieCressey/PHP-MySQL-S...sionHandler.php


Czyli ten przyklad jest zly? Czy ot tak to podales.


Cytat(Pyton_000 @ 30.03.2019, 16:42:55 ) *
To ja odpowiem. Jeśli nie wiesz po co Ci to to odpowiedź jest NIE

Jeszcze tylko jakbys mogl uścislic do czego to NIE sie tyczy to by bylo fsjnie
Pyton_000
Do trzymania sesji w bazie. Generalnie dla ciebei trzymanie sesji gdzielolwiek poza tym co jest standardowo nie ma sensu.
zdun
Cytat(Pyton_000 @ 30.03.2019, 20:34:25 ) *
Do trzymania sesji w bazie. Generalnie dla ciebei trzymanie sesji gdzielolwiek poza tym co jest standardowo nie ma sensu.

Zadawalem konkretne pytania. Od tego jest forum
Nie wszedlem i nie oczekiwalem zeby ktos za mnie cos zrobil tylko chcialem uzyskac odpowiedzi a nie zostawac odsylany gdzie indziej. Nic sie nie dowiedzialem procz insynuacji ze jestem leniwy i nic nie wiem.

Jakos sobie poradze sam.
Pyton_000
Odpowiedziałem na Twoje pytanie ogólne więc nie bardzo wiem jaki masz problem. Podałem Ci link do dokumentacji, powiedziałem jak by było lepiej żebyś zrobił, powiedziałem nawet żebyś poczytał komentarze z dokumentacji. Zrobiłeś to wszystko? Nie bardzo.
zdun
oj tak, Ty wiesz najlepiej co zrobilem a czego nie. Śmiechu warte. Nie odpowiedziales mi na zadne pytanie konkretnie.
viking
Ja ci wstawiłem gotowy kod ale widac też z tego nie skorzystałeś raczej.
Pyton_000
Cytat(zdun @ 3.04.2019, 14:06:03 ) *
oj tak, Ty wiesz najlepiej co zrobilem a czego nie. Śmiechu warte. Nie odpowiedziales mi na zadne pytanie konkretnie.

Oh jaki Ty biedny.
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-2024 Invision Power Services, Inc.