Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP][MySQL] Losowanie Unikalnego ID
rex
post
Post #1





Grupa: Zarejestrowani
Postów: 15
Pomógł: 0
Dołączył: 25.11.2009

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


Cześć wszystkim,

Tworzę sobie projekt w którym jedną z funkcji jest system losowania cytatów (taki quiz). Poniższy skrypt działa w sumie w 85% w takim stopniu w jakim chciałbym aby działał, jednakże brakuje tych najistotniejszych 15%.

1. Użytkownik wybiera poziom trudności
2. Biorąc pod uwagę wybrany poziom (lub brak) wyświetla treści adekwatne do wybranego
3. Projekt opiera się o 3 tabele w bazie danych, które posiadają cytaty o trzech stopniach trudności. W przypadku wybrania poziomu łatwego (1 baza) wskazuje nam tylko cytaty z pierwszej bazy itd. W przypadku wybrania całej bazy, system losuje jedną z trzech baz.

Teraz chciałbym przejść do problemu, który napotkałem (jestem samoukiem, stąd chciałbym poradzić się u bardziej doświadczonych osób ). Na wstępie podam skrypt/kod (prędzej jest tylko wyciągnięcie numeru id/loginu użytkownika z sesji, co nie ma wpływu na zaistniały problem:

  1. <?php
  2. // Pobieramy wybrany przez użytkownika poziom trudności cytatu
  3. $ido = (int)$_GET['poziom'];
  4.  
  5. // Jeśli wybrano poziom trudności, ustalamy jego nazwę
  6. if($ido == 1)
  7. $poziomtrudnosci = "Łatwy";
  8. else if($ido == 2)
  9. $poziomtrudnosci = "Średni";
  10. else if($ido == 3)
  11. $poziomtrudnosci = "Trudny";
  12. else if($ido == 4)
  13. $poziomtrudnosci = "Cała baza";
  14. else
  15. $poziomtrudnosci = "Nie wybrano";
  16.  
  17. // Sprawdzamy czy użytkownik rozpoczyna dopiero test czy jest już w jego trakcie
  18. if($ido == NULL)
  19. {
  20. // Tworzymy podstawowe wartości dla użytkownika, który zaczyna test
  21. $button = "";
  22. $cytat = "Wybierz poziom trudności aby rozpocząć!";
  23. }
  24. else
  25. {
  26. // Jeżeli wybrano całą bazę, losujemy ją
  27. if($ido == 4)
  28. {
  29. // Losujemy poziom trudności
  30. $wylosowanabaza = rand(1, 3);
  31. }
  32. else
  33. {
  34. // Ustawiamy poziom trudności taki jak wybrano w formularzu
  35. $wylosowanabaza = $ido;
  36. }
  37.  
  38. // Sprawdzamy, który stopień trudności cytatów wybrano
  39. if($ido == 1 or $ido == 2 or $ido == 3)
  40. {
  41. // Ustalamy bazę danych, którą wybieramy
  42. $bazadanych = "cytaty$wylosowanabaza";
  43.  
  44. // Połączenie z baza danych MySQL
  45. include("polaczenie.php");
  46.  
  47. // Pobieranie najwyższego ID
  48. $pobierzID = "SELECT ID FROM $bazadanych WHERE ID > 0 ORDER BY ID DESC";
  49. $daneID = mysql_query($pobierzID);
  50. $wierszID = mysql_fetch_row($daneID);
  51.  
  52. // Ustalamy zakres losowanego ID
  53. $minID = 1;
  54. $maxID = $wierszID[0];
  55.  
  56. // Losujemy ID
  57. $wylosowanyID = rand($minID, $maxID);
  58.  
  59. // Pobieranie pola test użytkownika z bazy danych
  60. $pobierzpoletest = "SELECT test FROM uzytkownicy WHERE ID = $id";
  61. $danepoletest = mysql_query($pobierzpoletest);
  62. $wierszpoletest = mysql_fetch_row($danepoletest);
  63.  
  64. // Ustalamy nazwę dla naszej zmiennej
  65. $uzytecytaty = "$wierszpoletest[0]";
  66.  
  67. // Ustalamy formę dla wybranego ID na podstawie poziomu trudności
  68. if($ido == 1)
  69. $kod = "L";
  70. else if($ido == 2)
  71. $kod = "S";
  72. else if($ido == 3)
  73. $kod = "T";
  74. else
  75. $kod = "";
  76.  
  77. // Tworzymy kod
  78. $calykod = "$kod$wylosowanyID";
  79. $lancuch = strstr($uzytecytaty, $calykod);
  80.  
  81. if($lancuch === false)
  82. {
  83. echo("Pokazuje cytat, którego nie było");
  84. }
  85. else
  86. {
  87. do
  88. {
  89. // Losujemy kolejne ID
  90. $wylosowanyID = rand($minID, $maxID);
  91.  
  92. $calykod = "$kod$wylosowanyID";
  93. $lancuch = strstr($uzytecytaty, $calykod);
  94. }
  95. while(strstr($uzytecytaty, $calykod));
  96. echo("Wylosowano nowy cytat!");
  97. }
  98.  
  99. // Pobranie danych użytkownika
  100. $szukaj = "SELECT ID, tresc, skrot, ksiega, skrot2, ksiega2 FROM $bazadanych WHERE ID = '$wylosowanyID'";
  101. $dane = mysql_query($szukaj);
  102. $wiersz = mysql_fetch_row($dane);
  103.  
  104. // Zakończenie połączenia z bazą danych
  105. mysql_close($polaczenie);
  106.  
  107. // Tworzymy button dla użytkownika, który jest w trakcie testu
  108. $button = "<a href=\"index.php?strona=sprawdz-odpowiedz&poziom=$ido&pytanie=$wiersz[0]&odp=a\"><button class=\"button-odpowiedz\" type=\"button\">$wiersz[3] ($wiersz[2])</button></a><a href=\"index.php?strona=sprawdz-odpowiedz&poziom=$ido&pytanie=$wiersz[0]&odp=b\"><button style=\"margin-left: 2px;\" class=\"button-odpowiedz\" type=\"button\">$wiersz[5] ($wiersz[4])</button></a>";
  109.  
  110. // Pobieramy cytat
  111. $cytat = "<span style=\"font-weight: bold; \">&bdquo;$wiersz[1]&rdquo;</span><br />";
  112. }
  113. // OD TEGO MIEJSCA SKRYPT JEST TECHNICZNYM ZARYSEM, DORZUCIŁEM GO JEDYNIE ABY OSOBY, KTÓRE ZERKNĄ NA SKRYPT NIE MUSIAŁY MI PISAĆ, ŻE BRAKUJE TEJ CZĘŚCI
  114. else if($ido == 4)
  115. {
  116. // Ustalamy bazę danych, którą wybieramy
  117. $bazadanych = "cytaty$wylosowanabaza";
  118.  
  119. // Połączenie z baza danych MySQL
  120. include("polaczenie.php");
  121.  
  122. // Pobieranie najwyższego ID
  123. $pobierzID = "SELECT ID FROM $bazadanych WHERE ID > 0 ORDER BY ID DESC";
  124. $daneID = mysql_query($pobierzID);
  125. $wierszID = mysql_fetch_row($daneID);
  126.  
  127. // Ustalamy zakres losowanego ID
  128. $minID = 1;
  129. $maxID = $wierszID[0];
  130.  
  131. // Losujemy ID
  132. $wylosowanyID = rand($minID, $maxID);
  133.  
  134. // Pobranie danych użytkownika
  135. $szukaj = "SELECT ID, tresc, skrot, ksiega, skrot2, ksiega2 FROM $bazadanych WHERE ID = '$wylosowanyID'";
  136. $dane = mysql_query($szukaj);
  137. $wiersz = mysql_fetch_row($dane);
  138.  
  139. // Zakończenie połączenia z bazą danych
  140. mysql_close($polaczenie);
  141.  
  142. // Tworzymy button dla użytkownika, który jest w trakcie testu
  143. $button = "<a href=\"index.php?strona=sprawdz-odpowiedz&poziom=$ido&pytanie=$wiersz[0]&odp=a\"><button class=\"button-odpowiedz\" type=\"button\">$wiersz[3] ($wiersz[2])</button></a><a href=\"index.php?strona=sprawdz-odpowiedz&poziom=$ido&pytanie=$wiersz[0]&odp=b\"><button style=\"margin-left: 2px;\" class=\"button-odpowiedz\" type=\"button\">$wiersz[5] ($wiersz[4])</button></a>";
  144.  
  145. // Pobieramy cytat
  146. $cytat = "<span style=\"font-weight: bold; \">&bdquo;$wiersz[1]&rdquo;</span><br />";
  147. }
  148. else
  149. {
  150. // Nie wybrano jeszcze poziomu trudności
  151. }
  152. }
  153. ?>


Problem wygląda następująco i dotyczy tego kawałka kodu:

  1. // Tworzymy kod
  2. $calykod = "$kod$wylosowanyID";
  3. $lancuch = strstr($uzytecytaty, $calykod);
  4.  
  5. if($lancuch === false)
  6. {
  7. echo("Pokazuje cytat, którego nie było");
  8. }
  9. else
  10. {
  11. do
  12. {
  13. // Losujemy kolejne ID
  14. $wylosowanyID = rand($minID, $maxID);
  15.  
  16. $calykod = "$kod$wylosowanyID";
  17. $lancuch = strstr($uzytecytaty, $calykod);
  18. }
  19. while(strstr($uzytecytaty, $calykod));
  20. echo("Wylosowano nowy cytat!");
  21. }
  22.  
  23. // Pobranie danych użytkownika
  24. $szukaj = "SELECT ID, tresc, skrot, ksiega, skrot2, ksiega2 FROM $bazadanych WHERE ID = '$wylosowanyID'";
  25. $dane = mysql_query($szukaj);
  26. $wiersz = mysql_fetch_row($dane);
  27.  
  28. // Zakończenie połączenia z bazą danych
  29. mysql_close($polaczenie);
  30.  
  31. // Tworzymy button dla użytkownika, który jest w trakcie testu
  32. $button = "<a href=\"index.php?strona=sprawdz-odpowiedz&poziom=$ido&pytanie=$wiersz[0]&odp=a\"><button class=\"button-odpowiedz\" type=\"button\">$wiersz[3] ($wiersz[2])</button></a><a href=\"index.php?strona=sprawdz-odpowiedz&poziom=$ido&pytanie=$wiersz[0]&odp=b\"><button style=\"margin-left: 2px;\" class=\"button-odpowiedz\" type=\"button\">$wiersz[5] ($wiersz[4])</button></a>";
  33.  
  34. // Pobieramy cytat
  35. $cytat = "<span style=\"font-weight: bold; \">&bdquo;$wiersz[1]&rdquo;</span><br />";


Kod, który wylosuje ID, sprawdza za pomocą funkcji strstr() czy występuje dany cytat w bazie danych użytkownika (czy został już użyty - każdy użyty jest zapisywany w tabeli użytkowników w polu "test", przyjmuje on formę np. L3, L10, L100 itd. co oznacza L - łatwy, 100 numer ID).

W momencie kiedy mamy do wyboru np. trzy cytaty w bazie danych o stopniu łatwym i tylko ta baza została wybrana, dwa z nich zostały użyte, czyli znajdują się już w zmiennej $uzytecytaty, system poprawnie losuje 3 cytat, który pozostał w bazie danych i nie był użyty w quizie.

Problem pojawia się, kiedy każdy z cytatów został wykorzystany dla wybranego poziomu trudności, wtedy pętla wpada w nieskończoną. Próbowałem opcji break, endwhile niestety nic z tego nie zadziałało w sposób, który byłby rozwiązaniem tego problemu.

W związku z tym, że programistą nie jestem i robię to jako pasję (po prostu uczę się - dlatego też do Was napisałem), domyślam się, że problem może leżeć w konstrukcji pętli, może formie, wyborze rodzaju pętli.

Chciałbym poprosić o pomoc w rozwiązaniu mojego problemu. Za każdą z odpowiedzi będę bardzo wdzięczny.

Pozdrawiam
Piotr
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
nospor
post
Post #2





Grupa: Moderatorzy
Postów: 36 561
Pomógł: 6315
Dołączył: 27.12.2004




Masz jeszcze skopana tabele z cytatami, ktore user juz widzial. ma byc tabela:

USER_CYTAT z polami:
ID_USER, ID_CYTAT

Potem losowanie jest juz banalne:

select * from CYTATY where ID not in (SELECT ID_CYTAT from USER_CYTAT where ID_USER=id_usera) order by rand() limit 3

To tylko szybki szkic. Oczywiscie musi dojsc warunek na poziom itp ale idea bedzie wlasnia taka. Mozna jeszcze usprawnic losowanie bo order by rand() do optymalnych nie nalezy.
Go to the top of the page
+Quote Post

Posty w temacie


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

 



RSS Aktualny czas: 26.12.2025 - 21:53