Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Uncaught exception 'PDOException'
Forum PHP.pl > Forum > Przedszkole
kris01
Mam problem z błędem:

( ! ) SCREAM: Error suppression ignored for
( ! ) Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'ff89ccf6eb5cf4cbd6a3e85a6d952dee' for key 'uniq_info'' in C:\wamp\www\sklep\sessions.php on line 84
( ! ) PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'ff89ccf6eb5cf4cbd6a3e85a6d952dee' for key 'uniq_info' in C:\wamp\www\sklep\sessions.php on line 84


  1. <?php
  2.  
  3. class session{
  4.  
  5. private $id;
  6. private $ip;
  7. private $browser;
  8. private $time;
  9. private $user;
  10. private $salt;
  11.  
  12. public function __construct(){
  13. global $pdo, $request;
  14.  
  15. if(!isset($_COOKIE[SESSION_COOKIE])){
  16. $_COOKIE[SESSION_COOKIE] = ''; //sprawdzenie czy istnieje plik cookie. Jeśli nie ma, tworzone jest puste
  17. }
  18. else{
  19. if(strlen($_COOKIE[SESSION_COOKIE]) != SESSION_ID_LENGHT){
  20. $this->newSession(); //Jeśli istnieje cookie sprawdzana jest jego długość i pochodzenie
  21. }
  22. }
  23.  
  24. $stmt = $pdo->prepare('SELECT session_id, updated_at, salt_token, user_id, uniq_info, ip, browser FROM sessions WHERE session_id = :sid AND uniq_info = :info AND updated_at > :updated AND ip = :ip AND browser = :browser');
  25. //pobieranie z bazy danych informacji o sesji np. id
  26. $stmt->bindValue(':sid', $_COOKIE[SESSION_COOKIE], PDO::PARAM_STR);
  27. $stmt->bindValue(':updated', time() - SESSION_COOKIE_EXPIRE, PDO::PARAM_INT); // porównanie czasu wygaśnięcia
  28. $stmt->bindValue(':info', $request->getInfo(), PDO::PARAM_STR); //porównanie wygenerowanego hash'a
  29. $stmt->bindValue(':ip', $request->getIp(), PDO::PARAM_STR); //porównanie danych z request
  30. $stmt->bindValue(':browser', $request->getBrowser(), PDO::PARAM_STR);
  31. $stmt->execute();
  32.  
  33. if($session = $stmt -> fetch(PDO::FETCH_ASSOC)){ //sprawdzenie, czy sesja została odnaleziona w bazie
  34. $stmt -> closeCursor();
  35. $this->id = $_COOKIE[SESSION_COOKIE];
  36. $this->salt = $session['salt_token']; //Jeśli sesja została odnaleziona przypisywane są parametry sesji PHP z bazy danych.
  37. $this->ip = $session['ip'];
  38. $this->browser = $session['browser'];
  39. $this->time = $session['updated_at'];
  40.  
  41. setcookie(SESSION_COOKIE, $this->id, time() + SESSION_COOKIE_EXPIRE); //Aktualizowanie cookie w przypadku znalezienia istniejącego. Wstawiane jest id sesji i czas wygaśniecia.
  42.  
  43. $stmt = $pdo->prepare('UPDATE sessions SET updated_at = :time WHERE session_id = :sid');
  44. $stmt->bindValue(':sid', $_COOKIE[SESSION_COOKIE], PDO::PARAM_STR);
  45. $stmt->bindValue(':time', time(), PDO::PARAM_INT);
  46. $stmt->execute();
  47.  
  48. if($session['user_id'] != 0){
  49. // dla zalogowanego użytkownika
  50. $stmt = $pdo->prepare("SELECT login FROM users WHERE id = :uid");
  51. $stmt->bindValue(":uid", $session['user_id'], PDO::PARAM_INT);
  52. $stmt->execute();
  53.  
  54. $row = $stmt->fetchAll(PDO::FETCH_ASSOC);
  55. $user->setLogin($row[0]['login']);
  56. }
  57. else{
  58. $this->user = new user(true);
  59. }
  60. }
  61. else{ // Jeśli nie ma sesji w bazie, tworzona jest nowa.
  62. $stmt->closeCursor();
  63. $this->newSession();
  64. }
  65. }
  66.  
  67. function newSession(){ //funkcja tworzaca nową sesję
  68. global $pdo, $request;
  69. //tworzenie losowego identyfikatora sesji
  70. $this->id = random_session_id();
  71. $this->salt = random_salt(10);
  72. setcookie(SESSION_COOKIE, $this->id, time() + SESSION_COOKIE_EXPIRE);
  73.  
  74. //Wstawianie informacji o sesji do bazy danych:
  75. $stmt = $pdo->prepare('INSERT INTO sessions (session_id, updated_at, salt_token, user_id, uniq_info, browser, ip)
  76. VALUES (:session_id, :time, :salt, :user_id, :info, :browser, :ip)');
  77. $stmt->bindValue(':session_id', $this->id, PDO::PARAM_STR);
  78. $stmt->bindValue(':time', time(), PDO::PARAM_INT);
  79. $stmt->bindValue(':salt', $this->salt, PDO::PARAM_STR);
  80. $stmt->bindValue(':user_id', 0, PDO::PARAM_INT);
  81. $stmt->bindValue(':info', $request->getInfo(), PDO::PARAM_STR);
  82. $stmt->bindValue(':browser', $request->getBrowser(), PDO::PARAM_STR);
  83. $stmt->bindValue(':ip', $request->getIp(), PDO::PARAM_STR);
  84. $stmt->execute();
  85. $this->user = new user(true);
  86. }
  87.  
  88. function updateSession(user $user){
  89. global $pdo, $request;
  90. //TWORZENIE NOWEGO SESJI DLA UŻYTKOWNIKA ZALOGOWANEGO
  91. $newId = random_session_id();
  92. $newSalt = random_salt(10);
  93. setcookie(SESSION_COOKIE, $newId, time() + SESSION_COOKIE_EXPIRE);
  94.  
  95. $stmt = $pdo->prepare("UPDATE sessions SET salt_token = :salt, updated_at = :time, session_id = :newId, user_id = :uid WHERE session_id = :sid");
  96.  
  97. $stmt->bindValue(':salt', $newSalt, PDO::PARAM_STR);
  98. $stmt->bindValue(':time', time(), PDO::PARAM_INT);
  99. $stmt->bindValue(':newId', $newId, PDO::PARAM_INT);
  100. $stmt->bindValue(':uid', $user->getId(), PDO::PARAM_INT);
  101. $stmt->bindValue('sid', $this->id, PDO::PARAM_STR);
  102. $stmt->execute();
  103.  
  104. $this->id = $newId;
  105. $this->user = $user;
  106. }
  107. public function getSessionId(){
  108. return $this->id;
  109. }
  110.  
  111. public function getUser(){
  112. return $this->user;
  113. }
  114. }
  115. ?>


Ponieważ dopiero raczkuję w PHP, nie wiem jak rozwiązać problem. Przejrzałem kod kilka razy i wydaje się poprawny. Gdy w bazie MySQL nie ma wpisu sesji, wskazany bład nie występuje.
nospor
Problem z php nie ma zadnego związku....

To:
" Duplicate entry 'ff89ccf6eb5cf4cbd6a3e85a6d952dee' for key 'uniq_info' in"
jest błąd bazy a nie php.
Zas co do samego bledu to jest chyba oczywisty - duplikujesz wartosc dla klucza/kolumny uniq_info
kris01
Założenie jest takie, że wpis w bazie jest aktualizowany tym samym kluczem, ponieważ sesja ma określony czas ważności. Ponieważ generowany jest ten sam klucz, trzeba go zastąpić odświerzonym.
Niestety nie wiem jak poradzić sobie z problemem, aby błąd nie był generowany, a strona działała poprawnie.
Pyton_000
INSERT INTO -> REPLACE INTO
kris01
Po wprowadzeniu zmiany zaproponowanej przez Python_000 pojawił się inny problem:

Fatal error: Call to a member function setLogin() on a non-object in C:\wamp\www\sklep\sessions.php on line 56

  1. <?php
  2.  
  3. class session{
  4.  
  5. private $id;
  6. private $ip;
  7. private $browser;
  8. private $time;
  9. private $user;
  10. private $salt;
  11.  
  12. public function __construct(){
  13. global $pdo, $request;
  14.  
  15. if(!isset($_COOKIE[SESSION_COOKIE])){
  16. $_COOKIE[SESSION_COOKIE] = ''; //sprawdzenie czy istnieje plik cookie. Jeśli nie ma, tworzone jest puste
  17. }
  18. else{
  19. if(strlen($_COOKIE[SESSION_COOKIE]) != SESSION_ID_LENGHT){
  20. $this->newSession(); //Jeśli istnieje cookie sprawdzana jest jego długość i pochodzenie
  21. }
  22. }
  23.  
  24. $stmt = $pdo->prepare('SELECT session_id, updated_at, salt_token, user_id, uniq_info, ip, browser FROM sessions WHERE session_id = :sid AND uniq_info = :info AND updated_at > :updated AND ip = :ip AND browser = :browser');
  25. //pobieranie z bazy danych informacji o sesji np. id
  26. $stmt->bindValue(':sid', $_COOKIE[SESSION_COOKIE], PDO::PARAM_STR);
  27. $stmt->bindValue(':updated', time() - SESSION_COOKIE_EXPIRE, PDO::PARAM_INT); // porównanie czasu wygaśnięcia
  28. $stmt->bindValue(':info', $request->getInfo(), PDO::PARAM_STR); //porównanie wygenerowanego hash'a
  29. $stmt->bindValue(':ip', $request->getIp(), PDO::PARAM_STR); //porównanie danych z request
  30. $stmt->bindValue(':browser', $request->getBrowser(), PDO::PARAM_STR);
  31. $stmt->execute();
  32.  
  33. if($session = $stmt -> fetch(PDO::FETCH_ASSOC)){ //sprawdzenie, czy sesja została odnaleziona w bazie
  34. $stmt -> closeCursor();
  35. $this->id = $_COOKIE[SESSION_COOKIE];
  36. $this->salt = $session['salt_token']; //Jeśli sesja została odnaleziona przypisywane są parametry sesji PHP z bazy danych.
  37. $this->ip = $session['ip'];
  38. $this->browser = $session['browser'];
  39. $this->time = $session['updated_at'];
  40.  
  41. setcookie(SESSION_COOKIE, $this->id, time() + SESSION_COOKIE_EXPIRE); //Aktualizowanie cookie w przypadku znalezienia istniejącego. Wstawiane jest id sesji i czas wygaśniecia.
  42.  
  43. $stmt = $pdo->prepare('UPDATE sessions SET updated_at = :time WHERE session_id = :sid');
  44. $stmt->bindValue(':sid', $_COOKIE[SESSION_COOKIE], PDO::PARAM_STR);
  45. $stmt->bindValue(':time', time(), PDO::PARAM_INT);
  46. $stmt->execute();
  47.  
  48. if($session['user_id'] != 0){
  49. // dla zalogowanego użytkownika
  50. $stmt = $pdo->prepare("SELECT login FROM users WHERE id = :uid");
  51. $stmt->bindValue(":uid", $session['user_id'], PDO::PARAM_INT);
  52. $stmt->execute();
  53.  
  54. $row = $stmt->fetchAll(PDO::FETCH_ASSOC);
  55. $this->user = new user; //zmiana 1
  56. $user->setLogin($row[0]['login']);
  57. }
  58. else{
  59. $this->user = new user(true);
  60. }
  61. }
  62. else{ // Jeśli nie ma sesji w bazie, tworzona jest nowa.
  63. $stmt->closeCursor();
  64. $this->newSession();
  65. }
  66. }
  67.  
  68. function newSession(){ //funkcja tworzaca nową sesję
  69. global $pdo, $request;
  70. //tworzenie losowego identyfikatora sesji
  71. $this->id = random_session_id();
  72. $this->salt = random_salt(10);
  73. setcookie(SESSION_COOKIE, $this->id, time() + SESSION_COOKIE_EXPIRE);
  74.  
  75. //Wstawianie informacji o sesji do bazy danych:
  76. $stmt = $pdo->prepare('REPLACE INTO sessions (session_id, updated_at, salt_token, user_id, uniq_info, browser, ip)
  77. VALUES (:session_id, :time, :salt, :user_id, :info, :browser, :ip)');
  78. $stmt->bindValue(':session_id', $this->id, PDO::PARAM_STR);
  79. $stmt->bindValue(':time', time(), PDO::PARAM_INT);
  80. $stmt->bindValue(':salt', $this->salt, PDO::PARAM_STR);
  81. $stmt->bindValue(':user_id', 0, PDO::PARAM_INT);
  82. $stmt->bindValue(':info', $request->getInfo(), PDO::PARAM_STR);
  83. $stmt->bindValue(':browser', $request->getBrowser(), PDO::PARAM_STR);
  84. $stmt->bindValue(':ip', $request->getIp(), PDO::PARAM_STR);
  85. $stmt->execute();
  86. $this->user = new user(true);
  87. }
  88.  
  89. function updateSession(user $user){
  90. global $pdo, $request;
  91. //TWORZENIE NOWEGO SESJI DLA UŻYTKOWNIKA ZALOGOWANEGO
  92. $newId = random_session_id();
  93. $newSalt = random_salt(10);
  94. setcookie(SESSION_COOKIE, $newId, time() + SESSION_COOKIE_EXPIRE);
  95.  
  96. $stmt = $pdo->prepare("UPDATE sessions SET salt_token = :salt, updated_at = :time, session_id = :newId, user_id = :uid WHERE session_id = :sid");
  97. //dla właściciela danej sesji użytkownika
  98. $stmt->bindValue(':salt', $newSalt, PDO::PARAM_STR);
  99. $stmt->bindValue(':time', time(), PDO::PARAM_INT);
  100. $stmt->bindValue(':newId', $newId, PDO::PARAM_INT);
  101. $stmt->bindValue(':uid', $user->getId(), PDO::PARAM_INT);
  102. $stmt->bindValue('sid', $this->id, PDO::PARAM_STR);
  103. $stmt->execute();
  104.  
  105. $this->id = $newId;
  106. $this->user = $user;
  107. }
  108. public function getSessionId(){
  109. return $this->id;
  110. }
  111.  
  112. public function getUser(){
  113. return $this->user;
  114. }
  115. }
  116. ?>


Funkcja setLogin została stworzona w innym pliku:

  1. <?php
  2. class user{
  3. private $id;
  4. private $login;
  5. private $construct;
  6.  
  7. public function __construct($anonymous = true){
  8. if($anonymous == true) {
  9. $this->id = 0;
  10. $this->login = '';
  11. }
  12. $this->construct = true;
  13. }
  14.  
  15. public function setLogin($login){
  16. $this->login = $login;
  17. }
  18.  
  19. public function getLogin(){
  20. return $this->login;
  21. }
  22.  
  23. public function getId(){
  24. return $this->id;
  25. }
  26.  
  27. public function setId($id){
  28. $this->id = $id;
  29. }
  30.  
  31. public function isAnonymus(){
  32. return ($this->id == 0);
  33. }
  34.  
  35. public static function checkPasswords($login, $password){
  36. global $pdo;
  37.  
  38. $stmt = $pdo->prepare("SELECT id, login FROM users WHERE login=:login AND password=:password");
  39. $stmt->bindValue(":login", $login, PDO::PARAM_STR);
  40. $stmt->bindValue(":password", $password, PDO::PARAM_STR);
  41. $stmt->execute();
  42.  
  43. if($row = $stmt->fetchAll(PDO::FETCH_ASSOC)){
  44. //Jeżeli logowanie prawidłowe, zwracana jest wartość użytkownik
  45. $newUser = new user;
  46. $newUser->setId($row[0]['id']);
  47. $newUser->login = $row[0]['login'];
  48.  
  49. return $newUser;
  50. }
  51. else{
  52. return 0; //jeżeli logowanie nieprawidłowe, zwracana jest wartość 0
  53. }
  54. }
  55. }
  56. ?>
rad11
Wyglada tak jakbys nie stworzyl obiektu(albo Ja jestem slepy) w ktorym moglbys dobrac sie do tej metody probowales stworzyc obiekt $user = new user() i dopiero $user->setLogin() ? Albo $this->user->setLogin()?
kris01
Próbowałem stworzyć użytkownika:

$this->user = new user;
$user->setLogin($row[0]['login']);

Nie za bardzo wiem, jak poprawić, aby zaczęło działać. Jak na początku wspomnialem dopiero raczkuję w PHP i aktualnie czuję się jak dziecko we mgle. Dlatego zwróciłem się po pomoc. Moge udostępnić więcej kodu z projektu, jesli to pomoże.
rad11
A probowales
  1. $this->user = new user;
  2. $this->user->setLogin($row[0]['login']);

?
kris01
Dziękuje za podpowiedź. na razie bład nie występuje. Ponieważ nad całością jeszczę pracuje, więc możliwe, że jeszcze pomoc bedzie potrzebna.
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.