Skocz do zawartości

[php/mysql] Losowanie bez powrórzeń (porównywanie z bazą)


k0l3c

Rekomendowane odpowiedzi

Witam, męczę się nad funkcją która musi:

1. Wylosować liczbę z pewnego zakresu

2. Sprawdzić czy istnieje w bazie MySQL

3. Jeżeli istnieje, to znowu wylosować i tak do skutku

4. Jak będzie unikalna to dopiero kolejne działanie.

Może mi ktoś pomóc? :>

penguins.jpg

Odwiedzaj regularnie mój blog o seo na lukaszt.pl podobno warto ;)

Odnośnik do komentarza
Udostępnij na innych stronach

Nie przesadzajmy :D (może to przez zmęczenie nie mogę tego skleić)

Przykładowo kombinuje tak i wiem, że to nie ma prawa zadziałać:

$zap = mysql_query("SELECT liczba FROM tabela WHERE liczba='".$liczba."'");
while($odp = mysql_fetch_assoc($zap)) {
$liczba = rand(100, 200);
echo $liczba.'już istnieje w bazie';
}
echo $liczba.'nie istnieje w bazie!';

penguins.jpg

Odwiedzaj regularnie mój blog o seo na lukaszt.pl podobno warto ;)

Odnośnik do komentarza
Udostępnij na innych stronach

// Prototyp kodu

$wykonuj = true;
$ilemax = 0;
do
{
$losowa = rand(1,10000);
if(Zapytanie_do_bazy_czy_jest($losowa) == false)
{
 Dodaje_do_bazy_rekord($losowa);
 $wykonuj = false;
}
++$ilemax;
if($ilemax> 100)$wykonuj = false; // NP jesli losowanie 100 razy nie dało unikalnej kończę ....
}
while($wykonuj);

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

Ja bym zrobił najpierw zapytanie o liczby do bazy i zapisał do tablicy, a następnie sprawdzał wylosowane liczby funkcją in_array (tak samo można najpierw wygenerować "kilka" tych liczb w zależnosci od potrzeb).

Black Friday 2024

W topx.pl nawet 50% taniej! - codziennie nowe promo!

Odnośnik do komentarza
Udostępnij na innych stronach

Mion, jak zwykle na ratunek :P

Działa, ale.. czy to nie spowoduje zbędnego stresu przy tej ilości rekordów?

$licz = true;
do {
$numer = rand(844220, 844222);
$zap = mysql_query("SELECT numer FROM ".$PREFIX."users WHERE numer='".$numer."'");
if($odp = mysql_fetch_assoc($zap) == false) {
echo $dodaj_do_bazy;
$licz = false;
}
$licz = false;
}
while($licz);

kayman, być może masz rację. Miałem o to zapytać wcześniej.

Więc, przypisuję użytkownikom numer identyfikacyjny #999444 <-- sześć cyfr, a wolałbym nie lecieć kolejno jak z id, tylko losować.

Jeżeli skrypt powyżej ma przesadnie obciążać cokolwiek, to chyba wrócę do rozwiązania z id.. ;/

penguins.jpg

Odwiedzaj regularnie mój blog o seo na lukaszt.pl podobno warto ;)

Odnośnik do komentarza
Udostępnij na innych stronach

Zamiast losować wszystkie możesz użyć unixowego znacznika czasu czyli:

$lastId = pobierzOstatnieIdZBazy();
$kod = $lastId + time() + rand(0,1000);
//lub
$kod = Md5($kod);// satała ługość 32 znaki

Jeśli to nie jest aplikacja "bankowa" taki poziom unikalności ci w zupełności starczy :)

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

bardzo podobnie zapisuje obrazki :) przy odpowiednio długim numerku powtórzenie jest prawie niemożliwe


function rand_numer_string() {
$string ='';
for ($i = 1; $i<=12; $i++) {
$string .= rand(0,9); 
}
return $string;
}

function rand_file_name($ext) {
$goodfilename = true;
do {
$file = rand_numer_string().'.'.$ext;
if (file_exists('images/catimages/'.$file)) $goodfilename = false;
} while (!$goodfilename);
return $file;
} // end rand_file_name

function upload_obrazek() {
if ($_FILES['image']['name'] >'') {
$tmp_obrazek = $_FILES['image']['tmp_name']; 
$tmp_typ = $_FILES['image']['type'];
if ($tmp_typ == 'image/png' || $tmp_typ == 'image/jpeg' || $tmp_typ == 'image/gif') {
if ($tmp_typ == 'image/png') $typ = 'png';
if ($tmp_typ == 'image/jpeg') $typ = 'jpg';
if ($tmp_typ == 'image/gif') $typ = 'gif';
if(is_uploaded_file($tmp_obrazek)) {

$file = rand_file_name($typ);
$filename = 'images/catimages/'.$file;
move_uploaded_file($tmp_obrazek,$filename);
}
} else return false;
if ($g = getimagesize($filename)) {
if ($g[0] > 480 || $g[1] > 360) { unlink($filename); return false; } else return $file;

} else {
if (file_exists($filename)) { unlink($filename); return false; }
}
} else return false;
} 

Odnośnik do komentarza
Udostępnij na innych stronach

Właściwie to chciałbym zachować limit 6 znaków. Daje mi to wystarczającą unikalność.

System może i nie bankowy, ale również istotny, bo ma związek z finansami i to idzie na całą Polskę więc..

Ale w sumie co tam, równie dobrze mogą być cyferki kolejno po sobie. Ważne aby reszta była nieosiągalna, no i hasła oczywiście.

Dzięki za pomoc.

Eeh.. a jak zrobić aby nie (id) tylko inną komórkę przydzielał AUTO_INCREMENT ale od np. liczby 100000?

penguins.jpg

Odwiedzaj regularnie mój blog o seo na lukaszt.pl podobno warto ;)

Odnośnik do komentarza
Udostępnij na innych stronach

Nie działa tak.

$t_t_uzytkownikow = mysql_query("CREATE TABLE ".$PREFIX."users (id int AUTO_INCREMENT,
imie VARCHAR(20),
nazwisko VARCHAR(50),
adres VARCHAR(255),
tel VARCHAR(20),
mail VARCHAR(50),
numer int AUTO_INCREMENT=20,
haslo VARCHAR(255),
uprawnienia VARCHAR(20),
PRIMARY KEY(id))");

echo $t_t_uzytkownikow;

I to nie przez to, że drugi raz występuje w tym samym zapytaniu. Wg. szybkiego google, składnia jest dobra ;/

penguins.jpg

Odwiedzaj regularnie mój blog o seo na lukaszt.pl podobno warto ;)

Odnośnik do komentarza
Udostępnij na innych stronach

Właściwie to chciałbym zachować limit 6 znaków. Daje mi to wystarczającą unikalność.

Ale jaki problem Funkcja co napisałem:

$wykonuj = true;
$ilemax = 0;
$UNIQKEY = "ERROR";

do
{
$losowa = time() + rand(1,10000);
$UNIQKEY = substr(Md5($UNIQKEY), 3,9); // od zmieniesz na wlasna tak by miec od + ile z 32 znaków
if(Zapytanie_do_bazy_czy_jest($UNIQKEY) == false)
{
Dodaje_do_bazy_rekord($UNIQKEY);
$wykonuj = false;
}
++$ilemax;
if($ilemax> 100)$wykonuj = false; // NP jesli losowanie 100 razy nie dało unikalnej kończę ....
}
while($wykonuj);
if($UNIQKEY == "ERROR") die( "Nie udało sie wylosowac unikalnego klucza usera");
echo $UNIQKEY;

Do tego pole UNIQKEY typu INDEX UNIQUE i masz 100 % pewność, że klucz usera będzie niepowtarzalny oczywiście w zakresie na ile pozwala 6 znaków. Nic więcej nie musisz tworzyć.

===

I cała oracja od wylosowania klucza i dodania nowego rekodu z tym kluczem powinna być wykonywana w ramach "transakcji SQL" lub nałożonej blokadzie na tabele bys miał pewność, że w tym ułamku sekundy nikt inny nie powtórzy tej samej operacji i CUDEM dostanie ten sam key.

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę. Warunki użytkowania Polityka prywatności