Quiz mit Javascript erstellt - bitte um Code-Beurteilung

  • Zitat

    Zu Deinem Code in #78: Ist das nicht der alte Code, den ich ursprünglich mal verwendet habe und sind die oberen Zeilen, mit denen eine ID abgefragt wird, jetzt nicht überflüssig? Das fetch hatte ich dort in einer Schleife: while ($row = $statement->fetch()) ..., wo und wie ich es in den aktuellen Code einsetzen müsste, weiß ich nicht.

    Eine Schleife ist genau genommen überflüssig, weil Du ja in deinem Fall den Datensatz für genau eine ID aus der Datenbank liest und dabei kann nur eine Zeile im Ergebnis sein. D. h. dies dürfte den Zweck erfüllen:

    Von den ersten Zeilen ist dieses:

    $id = $_POST['id'];

    erforderlich, weil wir ja die ID für die DB-Abfrage brauchen. Die Fehlerbehandlung könnte man noch ausgefeilter machen, aber jetzt weißt Du ja, dass man die Ausgabe des Skripts im Netzwerk-Tab sehen kann und für das Debugging dürfte das genügen.


    Zitat

    Und eines frage ich mich auch noch: Ich kann derzeit lokal einen JSON-String in eine PHP-Datei laden, der von JavaScript weiterverarbeitet wird. Aber war nicht das eigentliche Ziel, die Inhalte des Quiz' nicht lokal abzulegen und immer nur die benötigten Teile aus der DB abzufragen? Irgendwie habe ich das immer noch nicht wirklich verstanden ...

    Das fett formatierte ist genau der Kern der Sache und wir sind ja gerade dabei, das aufzubauen.

    Dieses verstehe ich nicht: "Ich kann derzeit lokal einen JSON-String in eine PHP-Datei laden", jedenfalls wenn Du damit meinst, einen JSON-String aus einer Datei zu laden.

  • So, jetzt funktioniert's lokal. Aber erst, nachdem ich $row = fetch($statement); zu $row = $statement->fetch(); geändert hatte, wie ich es in meinem alten Script gesehen hatte, denn $row = fetch($statement); sei eine nicht definierte Funktion, meldeten Editor und PHP. Juhu, ich habe mal selbst was reparieren können. :)


    Wie geht's nun weiter? Mir ist die Abfolge (damit meine ich gar nicht den Code, sondern eher die Logik dahinter) noch immer nicht klar. Hier mal ein kleiner Dialog, was ich mir so denke:


    JavaScript: "Du, PHP-Script, ich würde gern das Spiel beginnen. Holst du mir Fragen und Antworten zu Frage 1 aus der DB? Ich mache dann HTML draus."


    PHP-Script: "Geht klar, ich schaue mal in die Datenbank nach ID 1 ... ja, hier hast du!"


    JavaScript: "Prima! Ich hab's ausgegeben, und der User hat die vierte Antwort angeklickt. PHP-Script, ist das denn richtig?"


    PHP-Script: "Moment, ich schaue wieder in der DB nach ... ja, passt! Und ich habe hier noch 50 Punkte, die kannst du dem User jetzt anzeigen!"


    JavaScript: "Habe ich, und dazu den Button für die zweite Frage. Wenn der User darauf klickt, machen wir dann alles wieder wie beim ersten Mal?"


    PHP-Script: "Machen wir! Du weißt aber hoffentlich, wann Schluss ist ..."


    Ich nehme also an, dass das PHP-Script immer wieder Kontakt zur Datenbank herstellen muss, weil es ja keine Daten vorlagern darf. Aber bräuchte ich dazu nicht nur eins, sondern mehrere PHP-Scripte? Denn, schauen wir mal in den aktuellen PHP-Code:


    Code
    1. $output = [
    2. 'id' => $id,
    3. 'question' => $row['question'],
    4. 'answers' => [],
    5. ];
    6. $output['answers'][] = $row['answer1'];
    7. $output['answers'][] = $row['answer2'];
    8. $output['answers'][] = $row['answer3'];
    9. $output['answers'][] = $row['answer4'];


    Hier werden ja nur Frage und Antworten abgelegt, mehr kennt das PHP-Script noch nicht. Müsste das JavaScript für die Ermittlung der Lösung und Anzeige der gewonnenen Punkte dann ein weiteres PHP-Script ansprechen? Oder bin ich auf dem Irrweg und/oder einfach zu voreilig?

  • Zitat

    Müsste das JavaScript für die Ermittlung der Lösung und Anzeige der gewonnenen Punkte dann ein weiteres PHP-Script ansprechen?

    Genau so ist es, für das Holen der Lösung, nachdem der Benutzer sich für eine entschieden hat, brauchst Du ein weiteres PHP-Skript.

  • Jetzt kommt langsam Licht ins Dunkel! Ein wunderbares Gefühl, nachdem ich wirklich lange blind umhergeirrt bin. Ja, ich gewinne eine Vorstellung dessen, was zu tun ist, ein Wunder, ein Wunder! :)


    Ich glaube, ich komme nun voran und kann die einzelnen Werte aus dem ersten Array zu HTML wandeln. Und dann schaue ich weiter. Sollte ich am Ende wirklich etwas gelernt haben? Vielen, vielen Dank für den Support, Sempervivum , auch wenn ich mich damit (gern) wiederhole ...

  • Hier noch etwas zu jenem Problem, dass das Ganze online nicht funktioniert. Ich habe meine DB, das PHP-Script und auch die HTML-Seite auf einen weiteren (privaten) Webspace geladen, auch hier ohne Erfolg. In beiden HTML-Seiten bekomme ich einen Fehler in der Konsole angezeigt:


    Bei bplaced: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 3


    Beim privaten Webspace: Uncaught (in promise) SyntaxError: Unexpected end of JSON input


    Bei beiden folgt dann:


    Promise.then (async)

    (anonymous) @ o03.html:22


    Zeile 22 ist diese Zeile im JavaScript:

    }).then(res => {


    Aber lokal funktioniert doch alles ...


    PHP-Fehler gibt es übrigens keine, ich konnte auf meinem Webspace die Fehlermeldungen einschalten.

  • Sempervivum Entschuldige bitte, die spitze Klammer war ein blöder Fehler von mir (ich bin mit den Zugangsdaten durcheinander gekommen). Jetzt gibt es online nur noch "Unexpected end of JSON input".


    Ich werde in den nächsten Tagen mal schauen, ob ich dazu eine Info bekomme, die ich auch verstehe (die Gewichtung liegt auf dem Nebensatz, den Infos gibt es genug). Für heute mache ich Schluss, sonst passiert noch mehr solcher Müll wie mit den Zugangsdaten.

  • Ich habe es lösen können. Mir ist hier doch tatsächlich die fehlerhafte Codierung auf die Füße gefallen, von der ich glaubte, sie zunächst ignorieren zu können. Aufgefallen ist es mir, als ich alle IDs durchgegangen bin – ID5 ist die erste ohne Umlaute, und dort trat das Problem nicht auf.


    m.scatello hatte mir in #75 einen Link genannt (danke!), durch den ich Abhilfe schaffen konnte - ein ;charset=UTF8 hinter dem Namen der war die simple Lösung. Während die Umlaute kürzlich nur falsch dargestellt wurden, haben sie im aktuellen Code einen bösen Fehler produziert.


    Sempervivum Ich habe die "kaputte" Version mal online gelassen – http://music-quiz.bplaced.net/o04.html –, da ich fragen möchte, ob ich mithilfe des Netzwerk-Tabs dieses Umlautproblem hätte feststellen können. Ich hatte mir dieses Tab ja gestern bereits angeschaut und bin dabei lediglich auf die Zeile 22 im JavaScript gestoßen, von der ich glaubte, sie sei fehlerhaft: }).then(res => {


    Hätte ich daraus auf die Umlaute schließen können bzw. müssen?

  • Zitat

    ob ich mithilfe des Netzwerk-Tabs dieses Umlautproblem hätte feststellen können.

    ...

    Hätte ich daraus auf die Umlaute schließen können bzw. müssen?

    Wohl kaum, denn dort ist die Response vollkommen leer. Begegnet mir zum ersten Mal, dass ein Problem mit dem Zeichensatz zum Totalversagen führt, sonst immer nur Schmierzeichen.

  • Ich bin auf meinem lokalen Server ein ganzes Stück weitergekommen. Ich kann eine Frage generieren und Antworten vorgeben. Erst beim Klick auf eine Antwort wird bei der Datenbank abgefragt, ob die Antwort richtig oder falsch ist, das Ergebnis wird angezeigt. Ich habe also das Ziel erreicht, dass die korrekte Antwort nicht im Quelltext zu finden ist. Das ist prima, aber etwas anderes ist gar nicht prima: Ich bin zu blöd, den Zähler um eine Stelle zu erhöhen ...


    Um das zu verdeutlichen, hier ein ganz abgespecktes Stück Code:



    In Zeile 1 wird der Zähler für die ID definiert.


    In Zeile 3 wird die Konstante oneQuestion definiert, sie bekommt die ID 1 zugewiesen. Anschließend wird mithilfe von PHP das Array angelegt.


    Ab Zeile 12 werden die Frage und die Antworten angezeigt. Das findet alles innerhalb der Konstante oneQuestion statt, da sonst ja gar nichts angezeigt wird. Ob das so korrekt ist ... ich bin sehr unsicher.


    Und nun würde ich mich gern durch die Fragen blättern (in meinem Beispiel geht es noch gar nicht um korrekte Antworten). Aber ich bekomme es nicht hin, die richtige Stelle zu finden, an der ein Klick-Event ein i++ so auslösen könnte, dass sich der Zähler auch wirklich erhöht und man die zweite Frage angezeigt bekommt.


    Irgendwie bin ich damit vor die Wand gefahren, vermutlich ist der Aufbau dieses Codes nicht korrekt. Könnte bitte jemand helfen?


    Wie kann ich den Zähler erhöhen? Klar, dass ich dazu noch ein klickbares Element anlegen muss, aber an welcher Stelle? Vielen Dank!

  • Das sieht doch schon mal gut aus, kein Grund, dir Sorgen zu machen, dass es nicht korrekt ist.

    Am besten das ganze, ohne das i = 1; in eine Funktion packen. Dann im HTML ein Button-Element einfügen und einen Eventlistener für "click" darauf registrieren. Darin kannst Du dann die Variable i erhöhen und durch Aufruf der Funktion die Frage und die Antworten holen und anzeigen.

    Und bei der Definition von i besser ein let davor setzen: let i = 1:

  • Herzlichen Dank für Deine schnelle Antwort! Und schon funktioniert das Blättern wie gewünscht. Jetzt passe ich noch den Code meines Spiels an und hoffe, dass es dort genauso einfach ist.


    Das let habe ich schlichtweg vergessen – prima, dass es Dir aufgefallen ist. Und auch prima, dass meine Codestruktur nicht so abwegig ist, wie ich erst dachte. :)

  • Ein Problemchen habe ich doch noch, deswegen hier ein simples Online-Beispiel:


    http://music-quiz.bplaced.net/


    Das Javascript: http://music-quiz.bplaced.net/animalgame.js


    Bis ich mich für eine Antwort entscheide, sehe ich die korrekte Antwort nicht im Quellcode. Wenn ich aber die falsche Antwort anklicke, wird die Datei "animalgame3.php" geladen, weil ich jetzt ja mit PHP in der DB nachschauen muss, was als korrekte Antwort hinterlegt ist, und mit dieser Datei ist auch die richtige Antwort im Quellcode der Seite abrufbar.


    Bei nur zwei Antwortmöglichkeiten ist das natürlich nicht weiter schlimm, aber bei vier Antworten ist es doch irgendwie unschön. Habe ich hier etwas falsch aufgebaut oder lässt es sich nicht anders lösen?

  • Du könntest es so lösen, dass Du nicht die richtige Antwort zurück lieferst sondern die ID und die gewählte Antwort an den Server schickst und dieser liefert dann nur ein boolean ob diese Antwort richtig war oder nicht.

    Dieser Beitrag wurde bereits 1 Mal editiert, zuletzt von Sempervivum ()

  • Als ich die Datenbank erstellt habe, kam mir bereits der Verdacht, dass es nicht gut ist, was ich da mache: Ich habe eine Spalte "trueanswer" angelegt und dort die jeweils richtige Antwort eingetragen. Schon allein die Redundanz war mir dabei nicht geheuer.


    Dein Vorschlag klingt gut, aber ich habe nicht die leiseste Vorstellung, wie ich ihn umsetzen könnte. Da sind zwei Dinge, die ich nicht weiß:


    1. Wie müsste die Datenbank strukturiert sein, wie wird der richtige Eintrag gekennzeichnet? Was ein Boolean ist, weiß ich aber. ;)


    2. Wie schicke ich etwas zum Server? Bisher habe ich ja immer nur etwas geholt, habe also per JavaScript PHP-Dateien angesprochen, die Daten geholt haben. Oder ist mit "schicken" dasselbe Vorgehen gemeint?

  • Zitat

    1. Wie müsste die Datenbank strukturiert sein, wie wird der richtige Eintrag gekennzeichnet?

    Wenn es nur eine Spalte "trueanswer" gibt, ist es einfach: Du brauchst nur die ausgewählte Antwort mit der zu vergleichen, die vom Client bzw. Browser kommt, sind sie gleich, lieferst Du true zurück, wenn nicht false.


    Zitat

    2. Wie schicke ich etwas zum Server? Bisher habe ich ja immer nur etwas geholt, habe also per JavaScript PHP-Dateien angesprochen, die Daten geholt haben.

    Doch, auch bisher schon schickst Du etwas an der Server, und zwar als POST-Parameter z. B. hier, indem Du dem Objekt oneQuestion die ID mit append hinzu fügst und es im Body der Anfrage einträgt:

    Code
    1. const oneQuestion = new FormData();
    2. oneQuestion.append('id', i);
    3. fetch('animalgame2.php', {
    4. method: 'post',
    5. body: oneQuestion
    6. }).then // usw.

    Beim Holen der Info "Antwort ist richtig" brauchst Du jetzt nur noch die gewählte Antwort ebenfalls hinzu zu fügen:

    Code
    1. // 3. Abfrage
    2. const trueAnswer = new FormData();
    3. trueAnswer.append('id', i);
    4. trueAnswer.append('choosen', questions.answers[j]);
    5. fetch('animalgame3.php', {
    6. method: 'post',
    7. body: trueAnswer
    8. }).then

    Statt der gewählten Antwort im Volltext könntest Du auch einfach nur den Index in der Datenbank eintragen und an den Server übertragen, das würde das Ganze etwas kompakter machen.