Zufallszahlen mit PHP

Zufallszahlen

Für viele Anwendungen braucht man zufällig generierte Zahlen, zum Beispiel wenn man zufällige Bilder aus einer Galerie anzeigen möchte. Meistens sollen es aber nur Zahlen innerhalb eines bestimmten Bereichs sein, oder es dürfen keine Zahlen doppelt vorkommen. Wie man in PHP solche Zufallszahlen generiert wird in diesem Artikel beschrieben.

Zufallszahlen generieren

In PHP gibt es zwei Funktionen zum generieren von (Pseudo-)Zufallszahlen, rand und mt_rand. Die Funktion rand ist, auch wenn es im PHP-Handbuch anders steht, etwas schneller als mt_rand. Dafür generiert die auf dem Mersenne-Twister Algorithmus basierende Funktion mt_rand etwas zufälligere Zahlen.

In der Benutzung unterscheiden sich die beiden Funktionen aber nicht:

$zufallszahl = rand(1, 10);
$zufallszahlmt = mt_rand(1, 10);

Die beiden Parameter geben den Wertebereich der generierten Zufallszahlen an, in diesem Beispiel werden also Zahlen zwischen 1 und 10 (inklusive 1 und 10) generiert. Ohne Parameter aufgerufen wird eine Zahl zwischen 0 und get_randmax() bzw. mt_getrandmax() generiert.

Ab PHP 4.2.0 wird der Zufallsgenerator automatisch initialisiert, es ist also nicht mehr nötig ihn vor der Benutzung von (mt_)rand mit srand bzw. mt_srand zu initialisieren. Man kann das natürlich trotzdem tun, zum Beispiel um eine bestimmte Reihe von zufälligen Zahlen zu erzeugen.

srand(123);
$a = rand(1, 100); // 7
$b = rand(1, 100); // 79
$c = rand(1, 100); // 21

Zufällige Farben

Eine kleine Funktion zum Erzeugen von zufälligen Farben im #RRGGBB-Format:

function zufallsfarbe() {
	return sprintf('#%06X', mt_rand(0, 0xFFFFFF));
}

Keine Zahl doppelt

Wenn man gleich mehrere Zufallszahlen benötigt ist es gar nicht so unwahrscheinlich das unter den zufällig generierten Zahlen ein paar Zahlen mehrfach vorkommen. Das kann aber unerwünscht sein, beispielsweise wenn man zufällige Bilder aus einer Galerie anzeigen möchte. Folgende Funktion erzeugt ein Feld von $anzahl zufälligen Zahlen von $von bis $bis ohne das dabei Zahlen doppelt vorkommen.

function zufallszahlen($von, $bis, $anzahl) {
	$zahlen = range($von, $bis);
	for ($i = 0; $i < $anzahl; $i++) {
		$a = rand(0, count($zahlen) - 1);
		$ergebnis[] = $zahlen[$a];
		array_splice($zahlen, $a, 1);
	}
 
	return $ergebnis;
}

Die Funktionsweise ist ziemlich simpel. Zu erst wird ein Feld mit allen Zahlen von $von bis $bis erstellt. Anschließend wird in einer for-Schleife immer eine Zahl aus dem Zahlenfeld zufällig ausgewählt und im Ergebnis-Feld gespeichert, dabei wird nach jeder Zahl selbige aus dem Zahlen-Feld entfernt (mittels array_splice), so dass keine Zahl mehrfach vorkommt.

Zufällige Feld-Elemente

Um ein zufälliges Element aus einem Feld auszuwählen kann die Funktion array_rand($feld, $anzahl = 1) verwendet werden. Der zweite Parameter ist optional, wird er weggelassen, gibt die Funktion den Schlüssel von einem zufällig ausgewählten Element zurück.

$feld = array('Element 1', 'Element 2', 'Element 3', 'Element 4', 'Element 5');
echo 'Zufälliges Element: ' . $feld[array_rand($feld)];
 
//Ausgabe z.B.: Zufälliges Element: Element 4

Ansonsten wird ein Feld mit $anzahl Schlüsseln von zufällig ausgesuchten Elementen zurückgegeben. Eine andere Möglichkeit besteht darin, die Reihenfolge der Elemente des Felds mit der Funktion shuffle($feld) zufällig zu mischen.

shuffle($feld);
foreach($feld as $element) echo $element . ' ';
 
// Ausgabe z.B.: Element 3 Element 5 Element 4 Element 1 Element 2

Zufallszahlen mit MySQL

MySQL bietet für Zufallszahlen die Funktion RAND(N) an. Diese gibt einen zufälligen Fließkommawert zwischen (einschließlich) 0 und 1.0 zurück. Der Parameter N ist ein Ausgangswert mit dem der Zufallszahlengenerator initialisiert wird, dieser ist aber optional.

SELECT RAND()
0.32349805470882

Eine Funktion die eine zufällige Zahl in einem bestimmten Bereich liefert ist in MySQL nicht enthalten, dazu muss man etwas rechnen:

SELECT (10 + (RAND() * 5))
14.893036694166 /* Zufällige Fließkommazahl zwischen 10.0 und 15.0 */

Um die Ergebnisse einer SQL-Abfrage zufällig anzuordnen kann ORDER BY RAND() verwendet werden.

SELECT * FROM `datenbank`.`tabelle` ORDER BY RAND()

Wenn man eine beschränkte Anzahl zufällig ausgesuchter Datensätze aus einer Tabelle auslesen möchte muss man noch mit LIMIT angeben wie viele Datensätze zurückgegeben werden sollen.

SELECT * FROM `datenbank`.`tabelle` ORDER BY RAND() LIMIT 3 
/* drei zufällig ausgewählte Datensätze */

ORDER BY RAND() ist allerdings ziemlich langsam, Informationen darüber wie man solche Abfragen schneller machen kann finden sich hier. Diesen Tipp habe ich von Markus.

Beispiel: Zufällige Bilder aus einem Verzeichnis

Eine Anwendung für die oft zufällige Zahlen benötigt werden ist eine Bildergalerie bei der zufällig ausgewählte Bilder angezeigt werden. Folgender Quelltext liest alle Dateien die sich in dem angegebenen Verzeichnis befinden ein und gibt eine bestimmte Anzahl zufällig ausgewählter Dateien in img-Tags aus.

$anzahl = 4;
$verzeichnis = 'test/';
if ($handle = opendir($verzeichnis)) {
	while (false !== ($bild = readdir($handle)))
		if (is_file($verzeichnis . $bild))
			$bilder[] = $bild;
	closedir($handle);
}
 
$zf_bilder = array_rand($bilder, $anzahl);
for($i = 0; $i < $anzahl; $i++)
	echo '<img src="' . $verzeichnis . $bilder[$zf_bilder[$i]] . '" alt="" />';

Es handelt sich hierbei allerdings nur um ein sehr simples Beispiel das noch stark erweitert werden kann.

Informationen

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (2 Bewertungen, Durchschnitt: 5,00 von 5)
Loading ... Loading ...
Kategorie: PHP, Programmierung
Ansichten: 6.178

Kommentare

Bisher wurden 4 Kommentare geschrieben.

Kommentar schreiben

XHTML: Folgende Elemente sind erlaubt: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Angetrieben durch Wordpress Thema erstellt von Antu