Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Unikatowy, losowy ID, Problem z wygenerowaniem
graft
post
Post #1





Grupa: Zarejestrowani
Postów: 110
Pomógł: 0
Dołączył: 24.03.2007

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


Witam wszystkich.

Napisałem prosty skrypt rejestracji użytkowników. Dodatkowo chcę, aby każdy z użytkowników otrzymywał unikatowy identyfikator o formacie (np. U1234567), czyli jak widać stała litera "U" oraz 7-cyfrowa unikatowa, losowa liczba.

Napisałem coś takiego:
  1. <?php
  2.  
  3.  $sql = "SELECT user_new_id FROM tbl_users";
  4.  $result = mysql_query($sql)
  5.  or die ("Błąd: " . mysql_error()); 
  6.  
  7.  do {
  8.  $istnieje = 0;
  9.  $wynik = '';
  10.  
  11.  for($i=0;$i<7;$i++) { //7-cyfrowa
  12.  $losuj = rand(0,9); 
  13.  $wynik .= $losuj;
  14.  }
  15.  $unikat = 'U'.$wynik;
  16.  
  17.  while($row = mysql_fetch_array($result)) {
  18. if($unikat==$row['user_new_id']) {
  19.  $istnieje = 1;
  20.  }
  21.  } //end while 
  22.  
  23. }
  24.  while ($istnieje == 1); //end do while
  25.  echo $unikat;
  26.  
  27. ?>


Niestety nie działa jak powinno. Tzn. jeśli jako pierwsza liczbę wylosuje ciąg którego nie ma w bazie to jest OK. Natomiast kolejna wylosowana liczba lubi się powtórzyć (dla ułatwienia ustawiłem 1-cyfrową liczbę i wpisałem do bazy U1-U7, czyli możliwe powinno być jedynie uzyskanie ciągów: U8,U9 oraz U0)

Jeśli ktoś widzi błąd lub zna lepszy sposób na rozwiązanie problemu unikatowego, losowego ID byłbym wdzięczny za wskazówki.
Go to the top of the page
+Quote Post
misiek172
post
Post #2





Grupa: Zarejestrowani
Postów: 656
Pomógł: 3
Dołączył: 26.10.2005
Skąd: Częstochowa

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


ale po co ci taki? nie wystarczy kolumna ID i auto_increment? przecierz czy bedzie user mial kod U12324 czy 12 to jedno i to samo (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

ale jeśli tak nalegassz to ustawiasz sobie w danej kolumnie powiedzmy ID właściwość UNIQUE (czy jakoś tak to sie pisze (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) )

i poprostu skrypt który generuje taki numerek z U i próbuje wklepac do bazy i intrukacja warunkowa IF numer sie nie wklepał to zgeneruj jeszcze raz i tak az sie zgeneruje nie powtarzalny (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Ten post edytował misiek172 24.03.2007, 18:06:40
Go to the top of the page
+Quote Post
graft
post
Post #3





Grupa: Zarejestrowani
Postów: 110
Pomógł: 0
Dołączył: 24.03.2007

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


Cytat(misiek172 @ 24.03.2007, 18:05:19 ) *
ale po co ci taki? nie wystarczy kolumna ID i auto_increment? przecierz czy bedzie user mial kod U12324 czy 12 to jedno i to samo (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Taki mam wymóg

Cytat(misiek172 @ 24.03.2007, 18:05:19 ) *
i poprostu skrypt który generuje taki numerek z U i próbuje wklepac do bazy i intrukacja warunkowa IF numer sie nie wklepał to zgeneruj jeszcze raz i tak az sie zgeneruje nie powtarzalny (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)


Może zadam pytanie tak: W jaki sposób właściwie porównać, czy wylosowana liczba nie występuje w bazie, a jeśli występuje, niech losuje nową(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) ?

Ten post edytował graft 24.03.2007, 19:11:17
Go to the top of the page
+Quote Post
devnul
post
Post #4





Grupa: Zarejestrowani
Postów: 1 470
Pomógł: 75
Dołączył: 21.09.2005
Skąd: że znowu

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


może poprostu rób identyfikatory kolejne a do wygenerowanego dodawaj milion i masz zawsze 7 cyfrowy uid
Go to the top of the page
+Quote Post
Babcia@Stefa
post
Post #5





Grupa: Zarejestrowani
Postów: 654
Pomógł: 17
Dołączył: 19.03.2006
Skąd: z kosmosu ;)

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


  1. <?php
  2. $powtarza_sie = '2323';
  3. while (true)
  4. {
  5. $losuj = rand(1, 100);
  6. if($losuj !== $powtarza_sie)
  7. break;
  8. }
  9. ?>


Tylko odpowiednio sobie go przerób.

@edit
OMG !
To robisz np.
  1. <?php
  2. $rand = rand(1, 3);
  3. if($rand == 1)
  4. $losuj = rand(10, 1000);
  5. elseif($rand == 2)
  6. $losuj = rand(100, 10000);
  7. else
  8. $losuj = rand(1000, 100000);
  9. echo 'Twój id: ' .$losuj;
  10. ?>


lub

  1. <?php
  2. $rand = rand(1000, 100000);
  3. $losuj = rand($rand, 10000000);
  4. ?>


Dziękuję, Babcia@Stefa

Ten post edytował Babcia@Stefa 24.03.2007, 19:50:50
Go to the top of the page
+Quote Post
devnul
post
Post #6





Grupa: Zarejestrowani
Postów: 1 470
Pomógł: 75
Dołączył: 21.09.2005
Skąd: że znowu

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


taa jasne Babciu, a jak w bazie będzie miał milion rekordów to napewno szybko wylosuje taki ktry będzie unikalny - good 4 you

Ten post edytował devnul 24.03.2007, 19:38:14
Go to the top of the page
+Quote Post
UDAT
post
Post #7





Grupa: Zarejestrowani
Postów: 442
Pomógł: 0
Dołączył: 27.12.2005

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


Zrób sobie skrypt generujący losową permutację liczb 7 cyfrowych i zapisującą ją do pliku.
Potem przy tworzeniu kolejnych userów dawaj kolejne linie z pliku jako UID.

Plik ze wszyskimi permutacjami 7 cyfrowych liczb zajmie około 10^7B = 10MB.
Możesz oczywiście przyciąć plik do np. 10^6 UID
Go to the top of the page
+Quote Post
Kicok
post
Post #8





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

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


Cytat
Zrób sobie skrypt generujący losową permutację liczb 7 cyfrowych i zapisującą ją do pliku.
Potem przy tworzeniu kolejnych userów dawaj kolejne linie z pliku jako UID.

Plik ze wszyskimi permutacjami 7 cyfrowych liczb zajmie około 10^7B = 10MB.
Możesz oczywiście przyciąć plik do np. 10^6 UID

Ale po co? (IMG:http://forum.php.pl/style_emoticons/default/blink.gif)


  1. <?php
  2.  
  3. // Inicjujemy generator liczb losowych dla PHP < 4.2.0
  4. srand( array_sum(explode(',', microtime())) );
  5. $istnieje = false;
  6. do 
  7. {
  8. // Losujemy liczbę
  9. $losuj = rand(0, 9999999);
  10.  
  11. // Jeśli jest zbyt krótka, to uzupełniamy ją zerami
  12. $losuj = str_repeat('0', 7-strlen($losuj)) . $losuj;
  13.  
  14. // Dodajemy 'U' na początku
  15. $losuj = 'U' . $losuj;
  16.  
  17.  
  18. // Sprawdzamy, czy ktoś ma już takie ID
  19. $result = mysql_query('SELECT 1 FROM tbl_users WHERE (user_new_id = '' . $losuj . '');');
  20. $istnieje = (mysql_num_rows($result) > 0);
  21. }
  22. while($istnieje);
  23.  
  24. // Znaleziono unikatowe ID:
  25. echo($losuj);
  26.  
  27. ?>


W przypadku 7 cyfr ciężko jest wylosować już wygenerowane ID, więc w znacznej większości przypadków wykonywane będzie jedno zapytanie SQL. No chyba, że przybędzie sporo wierszy w tej tabeli. Wtedy można się będzie zastanowić nad pobraniem wszystkich identyfikatorów do tablicy i sprawdzaniu unikalności przy pomocy in_array" title="Zobacz w manualu PHP" target="_manual

PS. Pisane z palca, mogą być błędy
Go to the top of the page
+Quote Post
devnul
post
Post #9





Grupa: Zarejestrowani
Postów: 1 470
Pomógł: 75
Dołączył: 21.09.2005
Skąd: że znowu

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


ale co będize przy powiedzmy paru milionach wpisów? w najlepszym wypadku będzie to bardzo wolno działało
Go to the top of the page
+Quote Post
graft
post
Post #10





Grupa: Zarejestrowani
Postów: 110
Pomógł: 0
Dołączył: 24.03.2007

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


Dzięki Kicok. Twoje rozwiązanie jest dla mnie jak najbardziej OK. 7-cyfrowy identyfikator powinien spokojnie wystarczyć i przypadków wygenerowania istniejącego numeru będzie raczej niewiele.

Mam tylko pytanie: Czy koniecznie muszę inicjować generator liczb losowych?
  1. <?php
  2. ?>

Czy mogę go w przypadku PHP5 pominąć?

Dlaczego gdy zainicjowany jest generator, przy odświeżaniu strony wylosowana liczba jest zawsze taka sama. Natomiast, gdy wyłącze generator losuje za każdym razem inną liczbę.
PS. Wiem, że to pytanie klasyfikuje się raczej do działu "przedszkole" - tak tylko pytam z ciekawości.


Pozdrawiam
Go to the top of the page
+Quote Post
JaRoPHP
post
Post #11





Grupa: Zarejestrowani
Postów: 675
Pomógł: 15
Dołączył: 7.11.2004
Skąd: Katowice

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


Cytat(graft @ 25.03.2007, 20:32:51 ) *
Mam tylko pytanie: Czy koniecznie muszę inicjować generator liczb losowych?

http://pl.php.net/manual/pl/function.rand.php
Cytat
Od PHP w wersji 4.2.0 nie ma potrzeby inicjalizować generatora liczb losowych funkcją srand() lub mt_srand(), ponieważ dzieje się to automatycznie.
Go to the top of the page
+Quote Post
misiek172
post
Post #12





Grupa: Zarejestrowani
Postów: 656
Pomógł: 3
Dołączył: 26.10.2005
Skąd: Częstochowa

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


ehh
no to sobie zrób to ID i autoincrement ale żeby nie zaczynało się od 1

tylko od np.: 50000 i bedzie liczyl

50001
50002

itd

i po wyciagnieciu dajesz przed id literke U (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
graft
post
Post #13





Grupa: Zarejestrowani
Postów: 110
Pomógł: 0
Dołączył: 24.03.2007

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


Cytat(JaRoPHP @ 25.03.2007, 23:16:33 ) *


Ojj proszę Cię! Nie odsyłaj mnie do manuala. Oczywiście, zajrzałem najpierw do niego, nie znalazłem odpowiedzi na pytanie: dlaczego gdy zainicjuje generator losuje ciągle taką samą liczbę gdy odświeżam stronę, a jeśli odznaczę inicjowanie wyświetla różne liczby przy odświeżaniu strony.

OK, może gdzieś tam na dole w przykładach w manualu jest odpowiedź. Ale mimo wszystko postanowiłem zadać to pytanie, skoro już jest ten post.

A teraz Ty mi dajesz linka, jakbym co najmniej pytał się o wyjaśnienie co robi "echo" :roll2:
Go to the top of the page
+Quote Post
misiek172
post
Post #14





Grupa: Zarejestrowani
Postów: 656
Pomógł: 3
Dołączył: 26.10.2005
Skąd: Częstochowa

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


takie komentarze możesz przemilczeć a nie robić komuś wyrzuty, nikt niewie kto ma jaki stan wiedzy PHP wiec chłopak odesłał cie do manuala, skad ma wiediec czy ty to czytales czy wogole wiesz jak wylaga skoro nie potrafisz sobie poradzic z głupim problemem unikatowości ID :| forum jest od tego aby pomagac a nie komentować posty
Go to the top of the page
+Quote Post
devnul
post
Post #15





Grupa: Zarejestrowani
Postów: 1 470
Pomógł: 75
Dołączył: 21.09.2005
Skąd: że znowu

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


nie no bez przesady - forum to przede wszystkim dyskusja a nie tylko pomoc - od pomocy to jest właśnie manual a od rozwiązywania wątpliwości, dyskusji itp forum
Go to the top of the page
+Quote Post
JaRoPHP
post
Post #16





Grupa: Zarejestrowani
Postów: 675
Pomógł: 15
Dołączył: 7.11.2004
Skąd: Katowice

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


Cytat(graft @ 25.03.2007, 21:33:13 ) *
Ojj proszę Cię! Nie odsyłaj mnie do manuala.
Nie odesłałem Cię do manuala @graft, tylko zacytowałem jego fragment, który jest odpowiedzią na Twoją wątpliwość (która mnie zastanawia, czy zadanie "Oczywiście, zajrzałem najpierw do niego" jest prawdziwe...):
Cytat(graft @ 25.03.2007, 20:32:51 ) *
Mam tylko pytanie: Czy koniecznie muszę inicjować generator liczb losowych?
Czy mogę go w przypadku PHP5 pominąć?
Go to the top of the page
+Quote Post
sf
post
Post #17





Grupa: Zarejestrowani
Postów: 1 597
Pomógł: 30
Dołączył: 19.02.2003
Skąd: Tychy

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


Nie róbcie tego w PHP. Tylko zrobić procedurę składowaną, która się tym zajmie. Ułatwi to np. późniejsze integracje z jakimś forum.
Go to the top of the page
+Quote Post
Kicok
post
Post #18





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

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


Cytat
nie znalazłem odpowiedzi na pytanie: dlaczego gdy zainicjuje generator losuje ciągle taką samą liczbę gdy odświeżam stronę, a jeśli odznaczę inicjowanie wyświetla różne liczby przy odświeżaniu strony.


srand() przyjmuje jako parametr liczbę całkowitą, która służy później do obliczania liczb pseudolosowych w funkcji rand(). A jako że w moim kodzie był błąd, to do funkcji przekazywana była zawsze liczba 0. Zamień sobie linijkę:
  1. <?php
  2. ?>

na:
  1. <?php
  2. srand( array_sum(explode(' ', microtime()))*10000 );
  3. ?>

lub na:
  1. <?php
  2. ?>

i problem zniknie.
Go to the top of the page
+Quote Post
Turgon
post
Post #19





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

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


Dla mnie śmieszny trochę problem. Ja bym to robił używając takich id jak sesji (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) :
  1. <?php
  2. $sid = md5(strtoupper(sha1(crypt(mt_rand()))));
  3. ?>


istnieje strasznie małe prawdopodobieństwo wystąpienia identycznego id...
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #20





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Cytat(graft @ 24.03.2007, 16:57:26 ) *
Witam wszystkich.

Napisałem prosty skrypt rejestracji użytkowników. Dodatkowo chcę, aby każdy z użytkowników otrzymywał unikatowy identyfikator o formacie (np. U1234567), czyli jak widać stała litera "U" oraz 7-cyfrowa unikatowa, losowa liczba.

Mam głupie pytanie, ale co za różnica czy zrobisz U0000001 i iterację czy wylosujesz? Przecież w końcu i tak się te liczby trafią...
Jak chcesz na starcie dużą liczbę, to wymyśl jakąś a potem odejmuj od niej, jak po odjęciu będzie <0 to to dodajesz do niej...
Bo generowanie losowego i spr. czy nie występuje jest głupie. Ale jak już koniecznie potrzebujesz i nic nie możesz z tym zrobić, to najrozsądniej użyć random i spr. czy już podane id nie istnieje.

PS Turgon to miały być cyfry dziesiętne nie szesnastkowe

Ten post edytował Sedziwoj 27.03.2007, 00:53:06
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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: 23.08.2025 - 04:26