WebWork Magazin - Webseiten erstellen lassen, Online Medien, html

Webhoster, Webhosting Provider und Domain registrieren

Home | Registrieren | Einloggen | Suchen | Aktuelles | GSL-Webservice | Suleitec Webhosting
Reparatur-Forum | Elektro forum | Ersatzteilshop Haushalt und Elektronik


Homepage und Webhosting-Forum

Scripte und Programme für PHP, MYSQL. Diskussionen zur Programmierung im Web. Fragen zu CMS, Blogsoftware, Shops, Newsletter und vielen weiteren Scripten.


Forum » PHP & MySQL » do-while schleife stürzt bei vielen durchläufen ab » Antworten
Benutzername:
Passwort: Passwort vergessen?
Inhalt der Nachricht: Fett | Kursiv | Unterstrichen | Link | Bild | Smiley | Zitat | Zentriert | Quellcode| Kleiner Text
Optionen: Emailbenachrichtigung bei Antworten
 

do-while schleife stürzt bei vielen durchläufen ab
von Ori
Du kannst Arrays sortieren, bevor du sie in die Datenbank donnerst. Außerdem legst du einfach einen UNIQUE-Index über alle Spalten mit den Zahlen an.

Im Beispiel mit vier Spalten:
1: 
2: 
3: 
4:
$lottozahlen = array(6, 42, 1, 12); // oder wo auch immer die herkommen
$lottozahlen = sort($lottozahlen);

$sql = 'INSERT INTO ziehungen (eins, zwei, drei, vier) VALUES (' . implode(', ', $lottozahlen) . ')';


Wichtig für das Sortieren ist, dass es tatsächlich Zahlen sind (sonst SORT_NUMERIC als zweiten Parameter übergeben). In das Datenbank müssen die Einträge natürlich sortiert sein, damit der UNIQUE-Index verhindert, dass eine neue Zeile eingefügt wird. Wenn du viele einfügen willst, benutz Prepared Statements.


Nachtrag: Achja, meine Datenbanktabelle ist nicht richtig sauber; eigentlich muss es eine zweispaltige Tabelle sein. Und eine einspaltige:
- ziehungen (ziehungsid) ziehungsid PRIMARY KEY
- ziehungen_lottozahlen (ziehungsid, lottozahl) UNIQUE über beide Spalten, ziehungsid FOREIGN KEY

Jede gespeicherte Ziehung erhält einen Eintrag in der Tabelle ziehungen und sechs Stück in der Tabelle ziehungen_lottozahlen. Aber dann verrät einem der Index nicht mehr direkt beim Einfügen, ob es diese Kombination schon gibt. (Jaja, das Abfragen geht relativ fix; es ist nur für Anfänger nicht leistbar.) Dass es so sein sollte, nennt sich übrigens Normalisierung. Fragt Wikipedia.
von Marly007
Ne, also in geschachtelten Schleifen führt man keine SQL-Skirpte aus.
Guck dir mal Dinge wie INSERT DELAYED an oder baue dir deinen Query-String in der Schleife und setze später einen Query ab in dem du alles auf einmal einfügst.
Aber doch nicht so viele Inserts in einer Schleifer oO
von boribori
Hallo zusammen, ich bin auf dem Code auch aufmerksam geworden, ich sitze gerade auch auf ein Tool dass die Lottozahlen auswerten soll und habe folgendes Problem.
Ich habe ein Query das in dem Suchfeld angegeben wird, z.B. ein String von (lottovergleich.com)Lottozahlen , dann werden diese per PHP als Array Elemente gespeichert, dann muss ich das ganze in MYSQL checken, hier kommt das Problem. Die Reihenfolge ist nicht immer ideal, beduetet z.B. bei den Lottozahlen 1 2 4 5 6 7 8, und die Gewinnzahlen 3 1 4 5 6 8 , ich habe 3 richtige, muss aber jede Spalte mit jede andere Spalte vergleichen und die reihenfolge ist völlig beliebig..hat jemand irgendeine Idee wie ich das lösen kann???
von languitar
Hm naja, nur für solche Sachen hättest du auch direkt in der DB arbeiten können ;)
von damilchmann
wurde doch alles schon geklärt das skript funzt in der letzten variante. bewirken sollte es, dass alle möglichen kombinationen von 6 zahlen aus 49 möglichen in eine datenbank geschriebe werden.

lerne php gerade und hab einfach was ausprobiert, ist nur für das verständnis für mich um zu lernen, wie es zusammenhängt und das kann ich besser, wenn es etwas ist, was ich nachvollziehen kann

mehr nicht ;)

selbst wenn ich versucht hätte nen gästebuch zu programmieren, auch wenn ich es nicht wirklich brauche, hätte man die frage stellen können. wozu
von languitar
Was soll das überhaupt bewirken?
von raiserle
könnte es an der speicherresource liegen, die php für dich zur verfügung hat?
ich hab mir den code aber auch nicht weiter angeschaut.

gruß raiserle
von damilchmann
jo, hast recht. das script wurde inzwischen aber mit hilfe von u.a. herrn 3DMax komplett umgestellt und damit sollte auch die lösung passen. anbei die neue variante

irgendwie geht aber keiner auf das while-schleifen-problem ein, weshalb nur 6 ausgeführt werden.

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26:
<?php 

require("connect2.inc.php");

for($n1=1; $n1<10; $n1++)
 for($n2=$n1+1; $n2<10; $n2++)
     for($n3=$n2+1; $n3<10; $n3++)
        for($n4=$n3+1; $n4<10; $n4++)
            for($n5=$n4+1; $n5<10; $n5++)
                for($n6=$n5+1; $n6<10; $n6++)
     {

            echo $n1.' '.$n2.' '.$n3.' '.$n4.' '.$n5.' '.$n6.'<br />';
  
            mysql_query("INSERT INTO lottozahlen 

VALUES('','$n1','$n2','$n3','$n4','$n5','$n6')");


     }

  //csv - fwrite($fp, $n1.','.$n2.','.$n2.','.$n2.','.$n2.','.$n2.'\n');


?>
von languitar
Kombinatorische Explosion nennt sich sowas. Das Script ist so definitiv nicht lauffähig. Üblicherweise ist die max_execution_time bei Servern auf 30 Sekundne gestellt und selbst das ist schon eine Qual. Da musst du dir wohl was anderes ausdenken. Nenbeibei ist das Überprüfen, ob Datensätze schon vorhanden sind, mit PHP völliger Murks. Sowas kann deine Datenbank viel schneller "SELECT COUNT(*) AS vorhanden FROM tabelle WHERE bedingung für den datensatz". Wenn dann in vorhanden eine 0 steht, weißt du, dass es den Datensatz noch nicht gibt. Das erspart dir die ganze Schleife.
von damilchmann
hmm, hab gerade mal ein wenig mehr über das script nachgedacht. ich bin jetzt bei 631 einträgen und bei jedem klick kommen 6 dazu und für die überprüfung von 631 einträgen braucht die db schon ca. 9 sec. wenn ich das im dreisatz hochrechne und die benötigte zeit für die einzelnen aufeinander folgenden schritte (6 Einträge überprüfen, dann 12, dann 18 usw.) dann komm ich bei 14.000.000 einträgen, die es ja an möglcihen kombinationen gibt, für die do-while auf eine benötigte zeit von 7387 jahren, also würde diese datenbank nie fertig werden.

ich hoffe ich irre mich, was meint ihr?

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32:
<?php 
$i = 1;
$teil = 0;
do

{
		$ergebnis = (9*$i/631);
		
		$teil = ($teil + $ergebnis);
		
		
		
		
		
		
		$i = ($i + 6);

} while ($i < 14000000);

$ii = ($i - 6);

echo "Bei ".$ii." Einträgen: "."</br>";

echo "benötigte Zeit: ".$teil." in Sekunden"."</br>";
$erg = ($teil /60);
echo "benötigte Zeit: ".$erg." in Minuten"."</br>";
$ergebnis1 = ($erg / 60);
echo "benötigte Zeit: ".$ergebnis1." in Studen"."</br>";



?>
von damilchmann
hallo, scheinbar belebe ich hier als einziger das forum.

also, ich hab nen scrip gefunden, welches zufällig 6 zahlen aus 49 ausgeibt. also lottozahlen. danke dafür an den spender.

ich hab mir daraus ein script gebastelt, welches die zufälligen zahlen dann in eine datenbank speichert, zuvor jedoch per do-while-schleife die bereits vorhandenen einträge in der datenbank überprüft, ob es keine doppelten gibt. und das ganze script ist noch mal von einer do-while-schleife imgeben, die von zähler 1 bis zähler < 13983817 was der anzahl der kombinationsmöglichkeiten für 6 aus 49 sind.

das script stürzt aber ab, es macht nur 6 einträge in die datenbank und dann geht es nicht weiter.

zugegeben, die 13983816 ist ne groe zahl und und mit zunehmender db-größe hat auch die interne do-while mehr zu tun, da hat die anlage zu rödeln aber selbst wenn ich das z.b. auf <50 für das schleifenende stelle stürzt sie ab. es funktiont entweder immer einzeln oder max, wenn es auf <7 stelle. dann trägt er 6 datensätze ein und dann muss ich wieder aktualisieren.

hab ich ein fehler im script oder woran könnte es liegen?

als milchmädchen-lösung könnte man die seite ja nach 10 sec wieder aufrufen, dann würde es auch nach und nach gehen. gibt es dafür ne möglichkeit in php oder hat einer ne ganz andere idee?

thx und hier mal das script:

achja, an der stelle: "datensatz schon vorhanden" stirbt das script, dort wäre es schön, wenn auch dort dann automatisch das script neu starten würde und nicht da stehen bleibt.
gibt es da sowas wie goto zeile 1 oder so?

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
83: 
84: 
85: 
86: 
87: 
88: 
89: 
90: 
91: 
92: 
93: 
94: 
95: 
96: 
97:
<?
// timeout30 für scriptlaufzeit ausser kraft setzen
ini_set("max_execution_time","0");
require("connect.inc.php");

$a = 1;

do

{

// die folgende Zeile erzeugt einen internen Startwert für den Zufallsgenerator 
		srand ((double)microtime()*1000000);
		
		// die Schleife wird sooft durchlaufen wie $i kleiner 7 ist, 
		// da wir ja 6 Zahlen brauchen
		for($i=1; $i<7; $i++){
		   $val = rand(1,49);
		   // $val ist eine zufällige Zahl zwischen 1 und 49
		
		   (!strpos(" ".$vals, "$val")) ? $vals .= $val." " : $i--;
		 // Ist $val noch nicht in $vals enthalten hänge es zzgl. Leerzeichen an
		 // wenn doch verringere $i um 1 damit am Ende 6 Zahlen rauskommen
		}
		
		
		$arrayLotto = explode(" ", trim($vals));
		// zum Sortieren verwandeln wir die Zahlen am Besten in ein Array
		// trim() entfernt das hintere Leerzeichen
		
		sort($arrayLotto);
		
		
		
		// Anzahl der Datensätze auslesen
		$query = ("SELECT lz_id FROM lottozahlen");
        $result = mysql_query($query); 
       
        $anzahl = mysql_num_rows($result);
        //echo "Anzahl der Datensätze: ".$anzahl."</br>";
		
		
		// Überprüfung ob arrayLotto schon vorhanden ist
		$i = 1;
		$anzahl++;				
			do 
				//so lange die vorhandenen datensätze überprüfen, bis übereinstimmung oder letzte id
				{
				$query1 = mysql_query("SELECT n1,n2,n3,n4,n5,n6 FROM lottozahlen WHERE lz_id = $i");
				$data = mysql_fetch_array($query1);
				
				if (in_array($data,$arrayLotto))
				
				{
				
				        echo "Datensatz schon vorhanden"."</br>";
				        die;
				
				}
				else
				
				{
				
				         echo " ";
				
				}
				
				
				$i++;
				} while ($i < $anzahl);
		
		
		// einzelnen Inhalte des Arrays auf einzelne neue Variabeln übertragen
		 $zahl1 = $arrayLotto[0];
		 $zahl2 = $arrayLotto[1];
		 $zahl3 = $arrayLotto[2];
		 $zahl4 = $arrayLotto[3];
		 $zahl5 = $arrayLotto[4];
		 $zahl6 = $arrayLotto[5];
		 
		 		 
		 mysql_query("INSERT INTO lottozahlen VALUES('','$zahl1','$zahl2','$zahl3','$zahl4','$zahl5','$zahl6')");
		
		
		
$a++;

} while ($a < 7);

$query = ("SELECT lz_id FROM lottozahlen");
        $result = mysql_query($query); 
       
        $anzahl = mysql_num_rows($result);
        echo "Anzahl der bisher eingetragenen Datensätze: ".$anzahl."</br>";


?>

Nach oben