portseven: Order by Date funktioniert nicht ganz

Tag,

hab ein Chat System Programmiert. Alles läuft perfekt außer das er mir nicht die neusten Chat's zuerst sortiert. Sitze seit 4 Stunden an dem Problem und versuche jedes mal neue Sachen aus, aber jetzt fehlt mir die Kraft dazu. Mir fallen einfach keine Wege mehr ein.

Ein Bsp: http://test.liscon.bplaced.net/messages.php

Weiß jemand eventuell einer von euch ne Lösung?

			<?php 
			$user = $pdo->prepare("
			SELECT * FROM user;");
			
			if(!$user->execute()) {
				print_r($user->errorInfo());
			}
			
			?>
			
	<?php	while($row = $user->fetch(PDO::FETCH_ASSOC)) { ?>
				<form class="left" action="" method="GET">
			<?php
			
				if($stmt = $pdo->prepare("
				SELECT
				msg.id,
				msg.user_id,
				msg.sender_id,
				msg.message,
				msg.date
				
				FROM msg
				
				
				WHERE msg.user_id = :user_id AND sender_id = :sender_id || msg.user_id = :sender_id AND msg.sender_id = :user_id ORDER BY date DESC LIMIT 1;"))
			 {
				
				}
				$stmt->BindParam(':user_id', $_SESSION['id']);
				$stmt->BindParam(':sender_id', $row['id']);
				
				if(!$stmt->execute()) {
					print_r($stmt->errorInfo());
			}
		
?>

				<?php while($row2 = $stmt->fetch(PDO::FETCH_ASSOC)) {  ?>
				<section class="all-user-list-msg">
	
				<a href="messages.php?u=<?php echo $row['id']; ?>">
				
					<p class="img">
					
					<img src="<?php echo $row['image']; ?>">
					
					</p>
		
					 <p class="username-text">
					 <?php echo $row['username']; ?>
					 </p>
				
					
		
		

						<p class="msg-weight">
						
						<?php echo $row2['message']; ?>
						
						</p>

					
					<p class="date">  	&#149; <?php $time = convertTime($row2['date']); echo $time; ?></p>
				</a>

		</section>
				
			
<?php 	
	}
} 
?>

akzeptierte Antworten

  1. Tach!

    hab ein Chat System Programmiert. Alles läuft perfekt außer das er mir nicht die neusten Chat's zuerst sortiert.

    Ist denn date ein sortierbares Feld? Von welchem Typ ist es?

      			 <p class="username-text">
      			 <?php echo $row['username']; ?>
      			 </p>
    

    Wenn du Werte ausgibst, musst du sie dem Kontext gerecht anpassen. Ansonsten hast du da eine XSS-Lücke drin

    dedlfix.

    1. Das gehört zu dem Bereich:

      			<?php 
      			$user = $pdo->prepare("
      			SELECT * FROM user;");
      			
      			if(!$user->execute()) {
      				print_r($user->errorInfo());
      			}
      			
      			?>
      			
      	<?php	while($row = $user->fetch(PDO::FETCH_ASSOC)) { ?>
      
      1. Tach!

        Das gehört zu dem Bereich: [...]

        Welchen Bezug hat diese Antwort auf die beiden Punkte meiner Antwort?

        dedlfix.

        1. Ja es ist sortierbar.

          1. Tach!

            Ja es ist sortierbar.

            Na dann ist ja alles in Ordnung. - Oder deine Definition von sortierbar stimmt nicht mit meiner überein. Wenn du mir nun noch die Frage nach dem Feldtyp von date beantworten könntest, kämen wie entweder weiter oder können die Sortierbarkeit als Ursache ausschließen. Ein Feld vom Typ DATE oder DATETIME wäre sortierbar, ein VARCHAR hingegen nur unter bestimmten Umständen.

            dedlfix.

            1. Timestamp

              Kann auch eventuell an meinen Code liegen.

              Wie hättet ihr es denn gemacht wenn eure Tabelle so aussieht:

              id | user_id | sender_id | message | date

              wenn ich Fragen darf?

              Mir fallen wirklich keine Ideen mehr ein..

              1. Tach!

                Wie hättet ihr es denn gemacht wenn eure Tabelle so aussieht:

                id | user_id | sender_id | message | date

                wenn ich Fragen darf?

                Ich frage nun zum letzten Mal nach dem Feldtyp. Aus den Feldnamen kann ich diese Information nicht entnehmen. Wenn du meine Fragen nicht beantwortest, kommen wir nicht weiter. Wenn du sie nicht verstehst, dann sag es bitte. Aber irgendwas anderes antworten ist nicht zielführend.

                Das naheliegendste, wenn sich etwas nicht so sortiert wie vorgesehen ist, dass es nicht sortierbar ist. Ich versuche die Ursache zu ergründen und brauche dazu Informationen, die ich aus der Problemschilderung und deinen bisherigen Antworten nicht entnehmen konnte. Natürlich kann es auch andere Ursachen haben, aber die suche ich erst dann, wenn die Frage nach der Sortierbarkeit eindeutig geklärt ist.

                dedlfix.

                1. Sorry, hab die am Anfang nicht verstanden.

                  Der Feldtyp von Date ist Timestamp. Oder meinst du etwas anderes. Sorry hab wenig Ahnung davon.

                  €: Die Wirkung Order by Date DESC/ASC bezieht sich auf die Message. Das heißt wenn ich ASC mache, zeigt er die Letze Naricht an. Bei Desc die neuste. Das weiß ich jetzt schonmal. Problem ist nur noch die neusten Beiträge nach oben zu sortieren bzw als erstes.

                  1. Tach!

                    Der Feldtyp von Date ist Timestamp. Oder meinst du etwas anderes. Sorry hab wenig Ahnung davon.

                    Wenig Ahnung ist mir egal. Programmieren ist die Kunst, das was man erreichen will, genau so zu formulieren, dass es die Maschine versteht. Dabei muss man sehr präzise formulieren, wenn man nicht gerade fette Systeme mit "Tu was ich meine"-Fehlerkorrekturen vor sich hat, beispielsweise Browser im Umgang mit HTML.

                    Gut, TIMESTAMP ist zwar nicht der richtige Typ für das Vorhaben, aber er ist erstmal grundsätzlich sortierbar. TIMESTAMP-Felder in MySQL haben eine eingebaute Magie und sollten nur dazu verwendet werden, wenn man diese Magie des austomatischen Ausfüllens und/oder Anpassens bei Änderungen haben möchte. Für alle anderen Anwendungen sind DATE, DATETIME oder TIME die richtigen Feldtypen.

                    Bitte unterscheide den Feldtyp TIMESTAMP in MySQL mit dem Unix-Timestamp, mit dem PHP seine Datums- und Zeitangaben auszudrücken pflegt. Um einen übergebenen Unix-Timestamp in ein DATETIME-Feld zu konviertieren kann man die MySQL-Funktion FROM_UNIXTIME() nehmen und UNIX_TIMESTAMP() für den Rückweg.

                    Es kann natürlich auch sein, dass du nicht den MySQL-Feldtyp TIMESTAMP meinst, sondern dass du einen Unix-Timestamp übergibst, das Feld aber tatsächlich ein anderer Typ ist.

                    Jedenfalls würde ich nun als nächstes das PHP zur Seite legen und erstmal mit dem phpMyAdmin oder ähnlichen Tools untersuchen, wie die Daten dort aussehen und ob da das Sortieren klappt. Und nicht zuletzt auch, ob die Where-Bedingung die gewünschten Datensätze liefern.

                    dedlfix.

                  2. Hallo portseven,

                    das SQL ist korrekt, das Problem steckt in der DB. Entweder strukturell oder inhaltlich. Es wäre ja z.B. denkbar, dass Du - irgendwie - beim Speichern der Sätze in der DB was falsch gemacht hast und gar nicht der erwartete Timestamp drinsteckt.

                    Timestamp ist übrigens in MySQL auf den klassischen Unix-Timestamp Bereich begrenzt: 1970 bis 2038. DATETIME ist das nicht, das geht bis ins Jahr 9999. Das solltest Du auf jeden Fall ändern.

                    Die Tabellenstruktur lieferst Du z.B. mittels phpMyAdmin wie folgt. Ich habe das mal mit einer phbBB-Forendatenbank gemacht.

                    1. Tabellenname auswählen
                    2. Auf Struktur klicken
                    3. Screenshot anfertigen, als Datei lokal speichern und über das Bild-Icon (über dem Foren-Eingeabefeld das 6. Icon) ab deinen Beitrag anhängen. Screenshots unter Windows gelingen mit dem Snipping-Tool, was Unix anbietet weiß ich nicht.

                    Danach drückst Du links neben Struktur auf "Anzeigen" und schickst uns auch davon einen kleinen Ausschnitt, in dem der Inhalt des Timestamp-Feldes erkennbar ist.

                    Rolf

                    --
                    sumpsi - posui - clusi
                    1. Danke das ihr die Mühe macht mir zu helfen!

                      1. Hallo portseven,

                        ok, das sieht erstmal gut aus.

                        Ich nehme mal an, dass Du beim INSERT die date-Spalte nicht selbst bestückst sondern Dich auf CURRENT TIMESTAMP als Default verlässt. Dann kann kaum etwas schiefgehen. Oder machst Du es anders?

                        Hast Du schon dedlfixens Empfehlung umgesetzt, die Query ohne ORDER BY und ohne LIMIT im phpMyAdmin laufen zu lassen, mit sinnvollen Konstanten für die Binde-Variablen :user_id und :sender_id. Siehst Du die erwarteten Sätze? Wenn nicht: Ersetze doch mal das || durch OR, vielleicht ist dein Server auf PIPES_AS_CONCAT eingestellt. Danach füge den ORDER BY hinzu. Findet die erwartete Sortierung statt? Ist der oberste Satz der korrekte?

                        Das ist eigentlich IMMER die Vorgehensweise, wenn man DB-Zugriffe entwickelt oder Probleme darin sucht; man führt die Query erstmal von Hand gegen die DB aus und überträgt sie dann erst ins Programm.

                        Rolf

                        --
                        sumpsi - posui - clusi
                        1. Hab die in PHPmyadmin ausgeführt. Alles klappt. Hab ohne Order By & limit und einmal mit ORder by Date alles klappt und sortiert auch nach Datum.

                          Nur irgendwie zeigt er es nicht an auf der Seite.

                          1. Tach!

                            Nur irgendwie zeigt er es nicht an auf der Seite.

                            Beim Programmieren gibt es keinen ominösen "er" der irgendwas macht oder auch nicht. Es ist immer ein konkretes Stück Code, das aus bestimmten Eingabedaten ein Ergebnis produziert. Wenn das Ergebnis nicht stimmt, muss man sich mal die Eingabedaten und den Verarbeitungsweg anschauen, und mit Debugging nachvollziehen. Das hilft noch nicht imemr, um die Lösung zu finden, aber es hilft, die konkrete Stelle zu finden. Das ist auch ein Vorgang, den du selbst durchführen musst, denn nur du hast deine konkreten Daten vorliegen, die du zu verarbeiten gedenkst. Das Finden der Stelle ist erstmal wichtig. Ungelöste Fragen kann man dann immer noch stellen, falls sich die Antworten aus diesen Untersuchungen nicht von selbst ergeben.

                            dedlfix.

                            1. Hallo dedlfix,

                              doch, irgendein ominöser "er" steckt in der Seite drin. Wenn ich sie aufrufe, werde ich presto pronto per HTTP 307 nach google geschossen. Tolles Anschauungsmaterial 😂

                              Rolf

                              --
                              sumpsi - posui - clusi
                              1. Ja das ist neu, das ich zu google geleitet werde. Wurde ich Opfer eines Hacker Angriff bzw eines XSS Angriff? Hab geschaut & das gefunden:

                                <script>window.location = "http://www.google.com/"; </script>

                                Das habe ich in meinem richtigen Code nicht drinne. Wenn ich mit User 12 eingeloggt bin passiert nichts nur bei User 10 (session id=10) .

                                1. Tach!

                                  Wurde ich Opfer eines Hacker Angriff bzw eines XSS Angriff?

                                  Vermutlich warst du Opfer deiner Unterlassungen, weil du den Kontextwechsel nicht beachtet hast.

                                  dedlfix.

                                  1. Und wie kann ich das Fixxen?

                                    Ein Bsp das du mir oben gezeigt hast:

                                    			 <p class="username-text">
                                    			 <?php echo $row['username']; ?>
                                    			 </p>
                                    

                                    Das ist doch was ganz normales. <p> Username </p> , mehr nicht.

                                    1. Tach!

                                      Und wie kann ich das Fixxen?

                                      Erstmal wäre es wichtig, das Problem und seine Lösung generell kennenzulernen: Kontextwechsel. Und dann wären die Ausgaben zu untersuchen und um die notwendigen Maskierfunktionen zu ergänzen.

                                      dedlfix.

                                      1. Ok war jetzt paar Stunden dran alles zu üben & zu fixxen. Jetzt noch ne kleine Frage am Rande. Mein User mit der ID 10 wird aber bei jedem Aufruf der Seite auf die Seite google weitergeleitet. Wie kann man das jetzt entfernen?

                                        Wenn ich die Seite aufrufe & schnell speichere bevor ich weitergeleitet werde, sehe ich das hier:

                                        <script>window.location = "http://www.google.com/";  </script>
                                        

                                        Aber in meinem richtigen Skript ist es nicht vorhanden. Wie kann ich es also jetzt entfernen bzw besser gesagt wo finde ich es überhaupt?

                                        1. Tach!

                                          Ok war jetzt paar Stunden dran alles zu üben & zu fixxen. Jetzt noch ne kleine Frage am Rande. Mein User mit der ID 10 wird aber bei jedem Aufruf der Seite auf die Seite google weitergeleitet. Wie kann man das jetzt entfernen?

                                          Wenn das immer noch passiert, hast du womöglich noch nicht alle Stellen beachtet, an denen du eine Ausgabe von Daten ins HTML vornimmst. Andererseits ...

                                          Aber in meinem richtigen Skript ist es nicht vorhanden. Wie kann ich es also jetzt entfernen bzw besser gesagt wo finde ich es überhaupt?

                                          ... kann es sich dabei auch um ein Caching-Problem handeln. Der Browser hat noch nicht die korrigierte Version und verfährt noch nach der alten.

                                          Du könntest nun den Cache löschen. Aber auch die Entwicklertools der Browser können helfen. Im Netzwerk-Tab gibt es (zumindest bei Chrome und Firefox) eine Checkbox, um die Cache-Verwendung zu unterbinden (solange die Entwicklertools göffnet sind). Das sollte auch ein Neuladen erzwingen.

                                          dedlfix.

                                          1. Hattest Recht, war noch nicht alles sanitiert. Jetzt klappt alles. Aber das Problem lag nicht am Kontektwechsel. Aufjedenfall danke das du und die anderen die Mühe gemacht habt mir zu helfen. Sorry das ich wieder Frage aber muss auf sicher gehen 😂

                                            Letze für Heute:

                                            Wenn ich in einem A-Tag einen Link habe wie diesen hier:

                                            <a href="<?php echo $row['id']; ?>">Link</a>

                                            Muss ich da ebenso htmlspecialchars anwenden oder eher filter_var($row['id'], FILTER_SANITIZE_NUMBER_INT) ?

                                            1. Tach!

                                              Hattest Recht, war noch nicht alles sanitiert. Jetzt klappt alles. Aber das Problem lag nicht am Kontektwechsel.

                                              Naja, du wirst sich ja wohl nicht selbst zu Google umgeleitet haben. So eine XSS-Injection (XSS=Cross side Scripting) besteht immer aus zwei Teilen, demjeningen der der eine Lücke ausnutzt und Texte eingibt, der als Code interpretiert werden kann, und demjenigen, der nicht beachtet hat, dass bestimmte Zeichen in bestimmten Kontexten eine Sonderbedeutung haben und zu maskieren sind, so dass sie lediglich als das Zeichen und nicht als Bestandteil von Code interpretiert werden.

                                              Wenn ich in einem A-Tag einen Link habe wie diesen hier:

                                              <a href="<?php echo $row['id']; ?>">Link</a>

                                              Muss ich da ebenso htmlspecialchars anwenden oder eher filter_var($row['id'], FILTER_SANITIZE_NUMBER_INT) ?

                                              Filtern ist eher dazu geeignet, ungewünschte Werte aus fachlichen Gründen zu entfernen. Filtern am Eingang um sicherheitstechnisch vorzubeugen halte ich für keine gute Idee, denn die Ausgabe von Daten muss zum Ausgabekontext passen, und das gilt für alle Daten, nicht nur für Nutzereingaben. Zudem gehen die Nutzerdaten oft verschlungene Wege und wenn man für alle möglichen Szenarien vorsorgen möchte, bleibt am Ende von den eigentlichen Daten nicht mehr viel übrig, oder sie sind hoffnungslos vermaskiert und damit auch kaputt.

                                              Nun zum konkreten Fall. Im Allgemeinen hat man bei einem Konstrukt wie dem obigen zwei geschachtelte Kontexte. Zum einen sind da die Daten, die in die URL eingefügt werden, wofür diese URL-gerecht behandelt werden müssen. Zum anderen fügst du dann diese URL in den HTML-Kontext ein, wofür die Regeln von HTML Anwendung finden müssen, um ein syntaktisch korrektes Ergebnis zu erzielen.

                                              Bei Daten in URLs muss man etwas aufpassen, denn einige Zeichen müssen erhalten bleiben, wie /, wenn sie Pfadbestandteile trennen sollen. Die URL-Kodierung darf also nur auf die eingefügten Daten, nicht aber auf die gesamte URL erfolgen. Die HTML-Kodierung für das Einfügen ins a-href-Attribut muss hingegen für den gesamten Attributwert, sprich die komplette URL erfolgen.

                                              $row['id'] klingt nach Datenbank als Quelle. Wenn das Feld vom Typ INT oder vergleichbar ist, dann können da nur Ziffern herkommen und die sind hier ungefährlich. Trotzdem würde ich hier das htmlspecialchars() nicht weglassen, schon um dem Leser zu zeigen, dass man diese Stelle nicht übersehen hat. Dass da nur Zahlen ankommen ist ja nicht direkt offensichtlich, sondern erst nachdem man sich den Feldtyp angeschaut hat. Alternativ kann bei Integerwerten auch intval() genommen werden, das stellt ebenfalls sicher, dass nur Zahlen durchkommen. Beide Möglichkeiten sind auch noch kürzer und einfacher zu notieren als der Aufruf von filter_var().

                                              Was mir aber seltsam erscheint: der Link soll lediglich eine ID sein? Also, technisch möglich wäre das und es gibt sicher auch sinnvolle Anwendungsfälle, es sieht nur recht ungewöhnlich aus.

                                              dedlfix.

                                              1. Danke für die hilfreiche Info einfach Top!!

  2. Hi,

    
    > 				SELECT
    > 				msg.id,
    > 				msg.user_id,
    > 				msg.sender_id,
    > 				msg.message,
    > 				msg.date
    > 				
    > 				FROM msg
    > 				
    > 				
    > 				WHERE msg.user_id = :user_id AND sender_id = :sender_id || msg.user_id = :sender_id AND msg.sender_id = :user_id ORDER BY date DESC LIMIT 1;"))
    
    

    date als Bezeichner für den Datums-Datentyp ist ein reserviertes Wort. Müßte als Spaltenname also maskiert sein (`date`) - oder mit dem Tabellennamen qualifiziert werden (so wie Du es auch im select-Teil gemacht hast - msg.date)

    Evtl. wird hier aufgrund der fehlenden Maskierung/Qualifizierung auch die date()-Funktion im Order-By ausgeführt - was zu zufälliger Sortierung führen würde, da die ja für alle Zeilen dasselbe Ergebnis liefert ...

    cu,
    Andreas a/k/a MudGuard

    1. Hat leider keine Wirkung.

      Sitze seit 4 Stunden dran hab alles ausprobiert. Es kann doch nicht so schwer sein es nach Datum zu sortieren <.< Finde es sehr komisch.

      1. Hi,

        Hat leider keine Wirkung.

        Sitze seit 4 Stunden dran hab alles ausprobiert. Es kann doch nicht so schwer sein es nach Datum zu sortieren <.< Finde es sehr komisch.

        Kommen denn, wenn Du order und limit wegläßt, die richtigen Datensätze zum Vorschein?

        Sprich: ist das überhaupt ein Sortier-Problem? Oder ist schon in den Bedingungen was anders, als Du es gerne hättest?

        Bei nochmaliger Betrachtung des Statements fallen mir die || auf. Wolltest Du hier or verwenden? (Bei einer Oracle-DB ist || der String-Concatenation-Operator)

        cu,
        Andreas a/k/a MudGuard

        1. Wenn ich order oder Limit weglasse, dann hat jeder Text ein Feld.

          Hier ein Bsp: http://test.liscon.bplaced.net/msg2.php

          Also jede Naricht, hat einen eignen Bereich dann.

        2. Hallo MudGuard,

          ob || eine Stringverkettung ist oder ein logisches Oder, das ist Einstellungssache.

          Wenn es ODER ist, ist die Query an der Stelle in Ordnung. Ist es eine Stringverkettung, würde etwas merkwürdiges entstehen: a=b=c - interpretiert als: (a=b)=c, d.h. es wird a mit b verglichen, was einen logischen Wert ergibt (repräsentiert als 1 und 0), und das wird mit c verglichen. In dem Fall würden völlig falsche Sätze selektiert.

          Rolf

          --
          sumpsi - posui - clusi
    2. Tach!

      date als Bezeichner für den Datums-Datentyp ist ein reserviertes Wort. Müßte als Spaltenname also maskiert sein (`date`) - oder mit dem Tabellennamen qualifiziert werden (so wie Du es auch im select-Teil gemacht hast - msg.date)

      Hat mein MariaDB grad nicht interessiert, das nimmt das date ohne weitere Zeichen.

      dedlfix.

  3. Hallo @portseven,

    hab ein Chat System Programmiert. Alles läuft perfekt außer das er mir nicht die neusten Chat's zuerst sortiert.

    Ich gehe mal durch deinen Code und stelle ein paar Verständnisfragen:

    $user = $pdo->prepare("
    SELECT * FROM user;");
    
    if(!$user->execute()) {
    		print_r($user->errorInfo());
    }
    
    • Hat das Newline im SQL-Statement einen Grund?
    • Warum selektierst du blind alle Felder per Wildcard und nicht ausschließlich die gewünschten?
    • Was passiert im Fehlerfall, wird da nur die errorInfo ausgegeben und das Programm läuft einfach weiter oder wird es ordnungsgemäß beendet?
    <?php	while($row = $user->fetch(PDO::FETCH_ASSOC)) { ?>
    		<form class="left" action="" method="GET">
    

    Du öffnest für jeden Eintrag in der Datenbank ein neues Formular, aber ich sehe nirgends typische Formularelemente oder das beendende </form>-Tag.

    	if($stmt = $pdo->prepare("
    				SELECT
    				msg.id,
    				msg.user_id,
    				msg.sender_id,
    				msg.message,
    				msg.date
    				FROM msg
    				WHERE msg.user_id = :user_id AND sender_id = :sender_id || msg.user_id = :sender_id AND msg.sender_id = :user_id ORDER BY date DESC LIMIT 1;"))
    			 {
    				
    				}
    				$stmt->BindParam(':user_id', $_SESSION['id']);
    				$stmt->BindParam(':sender_id', $row['id']);
    				
    				if(!$stmt->execute()) {
    					print_r($stmt->errorInfo());
    			}
    
    1. Du bereitest die gleiche Query in jedem Schleifendurchlauf vor. Der Sinn von Prepared Statements ist es gerade, einmal prepare aufzurufen und mehrmals bind.
    2. kannst du diese Query hier mit der oben in eine Query verheiraten.
    3. Der Rückgabewert von prepare wird ignoriert – wie sieht es mit der Fehlerbehandlung aus?
    4. Von welchem SQL-Spaltentyp ist denn dein msg.date-Feld?
    5. || vs. OR.
    				<?php while($row2 = $stmt->fetch(PDO::FETCH_ASSOC)) {  ?>
    				<section class="all-user-list-msg">
    	
    				<a href="messages.php?u=<?php echo $row['id']; ?>">
    				
    					<p class="img">
    					<img src="<?php echo $row['image']; ?>">
    					</p>
    
    • p class="img" mit lediglich einem img (ohne alt-Attribut!), das klingt prinzipiell nach einer figure – und das img trotzdem mit einem alternativen Text.
    • Die Kontextwechsel nach HTML und URI werden nicht behandelt.
    					<p class="date">  	&#149; <?php $time = convertTime($row2['date']); echo $time; ?></p>
    
    • Die vielen Leerzeichen tun zwar nicht weh, haben aber keine Funktion. Aber was macht das Steuerzeichen 149 da?
    • Die Ausgabe der Zeit kann ohne Zwischenvariable auskommen.

    Viele Grüße
    Robert

    1. Hallo Robert,

      Du bereitest die gleiche Query in jedem Schleifendurchlauf vor. Der Sinn von Prepared Statements ist es gerade, einmal prepare aufzurufen und mehrmals bind.

      Kommt drauf an - gerade bei PDO. Diesen Teil hab ich mir beim OP nicht angeschaut.

      bindParam bindet einen SQL Parameter an eine Variablenreferenz, d.h. man muss nicht pro Durchlauf erneut binden, es reicht, die gebundene Variable zu ändern.

      bindValue bindet einen SQL Parameter an einen Wert, das muss man einmal pro Durchlauf neu tun.

      Rolf

      --
      sumpsi - posui - clusi
      1. Hallo @Rolf B,

        aber das prepare muss doch trotzdem nur einmal ausgeführt werden, oder?

        Viele Grüße
        Robert

        1. Tach!

          aber das prepare muss doch trotzdem nur einmal ausgeführt werden, oder?

          Ja. Aber eigentlich muss die ganze Query nur einmal laufen, dann aber ohne Einschränkungen, beziehungsweise nur soweit eingeschränkt, dass alle Daten in der Ergebnismenge enthalten sind, die insgesamt ausgegeben werden sollen. Den Rest macht man dann mit der Gruppenwechsel-Technik. Die meiste Zeit wird sicher nicht beim Ermitteln der Daten sondern beim Request-Response-Spielchen zwischen PHP und DBMS für jede dieser Querys draufgehen.

          dedlfix.

          1. Moin @dedlfix,

            aber das prepare muss doch trotzdem nur einmal ausgeführt werden, oder?

            Ja. Aber eigentlich muss die ganze Query nur einmal laufen, …

            Korrekt.

            Viele Grüße
            Robert

            1. Tach!

              aber das prepare muss doch trotzdem nur einmal ausgeführt werden, oder?

              Ja. Aber eigentlich muss die ganze Query nur einmal laufen, …

              Korrekt.

              Das was ich meine, sehe ich aber in deinem Posting nicht. Ich meine wirklich nur einmal, also so, dass eine Execute-Ausführung die Daten für alle alle Nutzer liefert, nicht für jeden Nutzer ein eigenes Execute.

              dedlfix.

              1. Hallo @dedlfix,

                Das was ich meine, sehe ich aber in deinem Posting nicht. Ich meine wirklich nur einmal, also so, dass eine Execute-Ausführung die Daten für alle alle Nutzer liefert, nicht für jeden Nutzer ein eigenes Execute.

                ich zitiere mich selbst:

                1. Du bereitest die gleiche Query in jedem Schleifendurchlauf vor. Der Sinn von Prepared Statements ist es gerade, einmal prepare aufzurufen und mehrmals bind.
                2. kannst du diese Query hier mit der oben in eine Query verheiraten.

                Oder meinst du etwas Anderes?

                Viele Grüße
                Robert

                1. Tach!

                  Das was ich meine, sehe ich aber in deinem Posting nicht. Ich meine wirklich nur einmal, also so, dass eine Execute-Ausführung die Daten für alle alle Nutzer liefert, nicht für jeden Nutzer ein eigenes Execute.

                  ich zitiere mich selbst:

                  1. Du bereitest die gleiche Query in jedem Schleifendurchlauf vor. Der Sinn von Prepared Statements ist es gerade, einmal prepare aufzurufen und mehrmals bind.
                  2. kannst du diese Query hier mit der oben in eine Query verheiraten.

                  Oder meinst du etwas Anderes?

                  Vielleicht meinen wir dasselbe, aber dein Punkt 1 passt da nicht wirklich dazu, denn wenn lediglich eine Ausführung übrigbleibt, ergibt sich von selbst, dass eine Schleife nur noch das Fetchen erledigt und alles andere (Prepare, ggf. Bind, Execute) davor stattfindet.

                  dedlfix.