Ankündigung

Einklappen
Keine Ankündigung bisher.

Wiedereinsteiger mit Einstiegsschwierigkeiten // Quizaufgabe verwirrend

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Wiedereinsteiger mit Einstiegsschwierigkeiten // Quizaufgabe verwirrend

    Vorwort: Ich habe noch schemenhafte Ahnung, allerdings durch Programmieren von anderen Webseiten u.ä. vernachlässige auch ich manch etwas und vergesse oder verdränge das eine oder andere.

    Problem: Ich muss eine Aufgabe mit einer klaren Aufgabenstellung nachkommen, denke allerdings wahrscheinlich viel zu effizient, sprich ich würde diese Aufgabe zwar oberflächlich lösen, allerdings würde ich die Aufgabenstellung dabei nicht beachten.

    Aufgabenstellung: 8 Dateien. 1 HTML (dürfte nicht mein Problem sein), 1 CMS (ebenfalls kein Problem), 6 PHP, wovon 5 PHP-Datein jeweils eine Frage mit möglichen Antworten beinhaltet und zu guter Letzt eine weitere als Auswertung. Ohne hinterlegte Datenbank (was ich allerdings so gut wie nur noch kann), mit Session und Arrays.

    Mein Problem hierbei ist einfach nur diese Sache mit der Session und den Arrays. Mein Verständnis, nach öfteren wieder einlesen, dürfte sich aktuell bei 50-75% befinden, allerdings scheitert es komplett an der Umsetzung.

    So würde Frage1.php wie folgt aussehen:
    PHP-Code:
    <html>


    <head>

            <title>Quiz</title>

            <link rel="stylesheet" type="text/css" href="css/style.css" />
    </head>

    <body>

            <div id="page-wrap">

                    <form action="auswertung.php" method="post" id="quiz">



    <?php
    $quiz 
    = array(
        array(
            
    'Frage'=>'Frage 1',
            
    'Auswahl'=>array(
                
    'Antwort-1'// Richtig
                
    'Antwort-2',
                
    'Antwort-3',
                
    'Antwort-4'
            
    ),
            
    'richtige_antwort'=>
        
    ),
    );

                    </
    form>

            </
    div>

    </
    body>

    </
    html>
    Frage 2:
    PHP-Code:
    <html>


    <head>

            <title>Quiz</title>

            <link rel="stylesheet" type="text/css" href="css/style.css" />
    </head>

    <body>

            <div id="page-wrap">

                    <form action="auswertung.php" method="post" id="quiz">



    <?php
    $quiz 
    = array(
        array(
            
    'Frage'=>'Frage 2',
            
    'Auswahl'=>array(
                
    'Antwort-1'
                
    'Antwort-2',
                
    'Antwort-3'// Richtig
                
    'Antwort-4'
            
    ),
            
    'richtige_antwort'=>
        
    ),
    );

                    </
    form>

            </
    div>

    </
    body>

    </
    html>
    usw.

    Wie hat nun allerdings die Auswertungs.php auszusehen? Wo kommt die Session und wo die Arrays rein? Die auswert php soll jede Antwort ausgeben und diese als 'richtig' / 'falsch' erkenntlich machen. Und nein, ich möchte nicht direkt die komplette Lösung o.ä. erhalten, ich will nur Stücken bekommen und regelmäßig meinen Fortschritt mitteilen.

  • #2
    Willkommen im Forum.

    Erst mal: Was du an Code gepostet hast, ergibt leider kaum Sinn und ist sogar syntaktisch falsch. Das wird so nicht funktionieren. (PHP-Arrays beginnen zudem beim Index 0.)

    Dann brauchst du auch nicht für jede Frage eine eigene Datei. Das ist nicht sinnvoll. Nutze eine Datei zur Anzeige aller Fragen und wähle die aktuell dargestellte Frage über einen Parameter (in GET, POST oder SESSION).

    Das hier…

    Aufgabenstellung: 8 Dateien. 1 HTML (dürfte nicht mein Problem sein), 1 CMS (ebenfalls kein Problem), 6 PHP
    …ist auch deshalb nicht wirklich brauchbar, weil du ja schon selbst in deine PHP-Dateien auch HTML-Code schreibst und weil eine Datei „1 CMS“ nicht wirklich Sinn ergibt.

    Zu Sessions siehe zum Beispiel hier:

    - http://phpforum.de/forum/showthread.php?t=225402
    - http://php.net/manual/en/book.session.php

    Hier ein Umriss:

    PHP-Code:
    <?php

    $e 
    = function ($s) {
        return 
    htmlspecialchars(
            
    $s,
            
    ENT_QUOTES ENT_HTML5 ENT_DISALLOWED ENT_SUBSTITUTE,
            
    'UTF-8'
        
    );
    };

    $questions = array();

    $questions[] = array(
        
    'text' => 'Welches Tier wird als „bester Freund des Menschen“ bezeichnet?',
        
    'answers' => array('Hund''Katze''Maus''Schwein'),
        
    'correct_answer' => 0
    );

    $questions[] = array(
        
    'text' => 'Welche Farbe ist bei einem Regenbogen oben?',
        
    'answers' => array('Rot''Grün''Blau''Gelb'),
        
    'correct_answer' => 0
    );

    $questions[] = array(
        
    'text' => 'Welches ist die Hauptstadt von Assyrien?',
        
    'answers' => array('Persepolis''Karthago''Alexandria''Ninive'),
        
    'correct_answer' => 3
    );

    session_start();

    // Initialize
    if (!isset($_SESSION['answers'])) {
        
    $_SESSION['current_question'] = 0;
        
    $_SESSION['answers'] = array();
    } elseif (isset(
    $_POST['action'])) {
        if (
    $_POST['action'] === 'answer') {
            
    $_SESSION['answers'][$_POST['question_index']] = $_POST['answer_index'];
            
    $_SESSION['current_question']++;
        }
    }

    $evaluation true;
    $question_index null;
    $question null;
    $answers $_SESSION['answers'];

    if (
    $_SESSION['current_question'] < count($questions)) {
        
    $evaluation false;
        
    $question_index $_SESSION['current_question'];
        
    $question $questions[$_SESSION['current_question']];
        
    $answers null;
    }

    if (
    $evaluation) {
        
    // Reset session
        
    $_SESSION = array();
    }

    header('Content-Type: text/html; charset=UTF-8');

    ?>

    <?php if (false === $evaluation) : ?>

        <form method="post" action="<?=$e(basename(__FILE__))?>">
            <p><?=$e($question['text'])?></p>

            <?php $first true?>
            <?php foreach ($question['answers'] as $index => $text) : ?>
                <?php $checked = ($first) ? ' checked="checked"' ''$first false?>
                <p><input type="radio" name="answer_index" value="<?=$e($index)?>"<?=$checked?>><?=$e($text)?></p>
            <?php endforeach; ?>

            <p>
                <input type="hidden" name="question_index" value="<?=$e($question_index)?>">
                <input type="hidden" name="action" value="answer">
                <input type="submit" value="Senden">
            </p>
        </form>

    <?php else : ?>

        <h1>Auswertung</h1>

        <?php foreach ($questions as $question_index => $question) : ?>

        <p><?=$e($question['text'])?></p>
        <p>Richtige Antwort: <?=$e($question['answers'][$question['correct_answer']])?></p>
        <p>Ihre Antwort: <?=$e($question['answers'][$answers[$question_index]])?></p>
        <hr>

        <?php endforeach; ?>

        <p>Danke fürs Spielen.</p>

        <p><a href="<?=$e(basename(__FILE__))?>">Wiederholen</a></p>

    <?php endif; ?>
    Ansonsten fällt deine Fragestellung auch unter:

    - http://www.php.de/php-einsteiger/675...sumfragen.html

    Es gibt zig Wege, so was umzusetzen. Welchen du davon wählst, bleibt letztlich dir überlassen.

    Kommentar


    • #3
      Meine Worte: wenn es nach mir ginge, wäre es auch nur eine Datei mit allen Fragen, allerdings sieht sie Aufgabenstellung vor, dass jede Frage eine eigene Datei beinhaltet, unabhängig davon ob sinnvoll oder eben nicht sinnvoll.
      Sprich: Willkommensseite -> Frage 1 bei absenden -> Frage 2 -> ... -> Frage 5 bei absenden -> Auswertung aller 5 Fragen.

      Es sollte nicht CMS heißen, sondern CSS (Autokorrektur halt)

      Und dank' dir.

      Kommentar


      • #4
        Zitat von klassenbecher Beitrag anzeigen
        Sprich: Willkommensseite -> Frage 1 bei absenden -> Frage 2 -> ... -> Frage 5 bei absenden -> Auswertung aller 5 Fragen.
        dazu brauchjste keine masse an dateien.
        http://php-de.github.io/#form
        http://php-de.github.io/jumpto/affenformular/

        Kommentar


        • #5
          Ach, hab die Aufgabe eh falsch genannt bekommen, es würde wie folgt aussehen:
          Willkommensseite HTMl -> Frage 1 HTMl -> Frage 2 HTML -> ... -> Frage 5 HTML -> Auswertung in PHP. Als Zwischenspeicherung der getätigten Antworten, die Verwendung von Arrays benutzen.

          Da allerdings dieser Thread wohl laut http://www.php.de/php-einsteiger/675...sumfragen.html ungültig ist, kann man diesen closen. Trotz allem dennoch ein Danke schön.

          Kommentar


          • #6
            Wir haben ein Projektverzeichnis, das die beiden Verzeichnisse "output" und "src" enthält, und außerdem eine Datei "generate.php".

            Das "output"-Verzeichnis ist leer, muss aber von den Rechten her für PHP beschreibbar sein.

            Das "src"-Verzeichnis enthält die folgenden 5 Dateien:

            src/questions.php

            Die Daten für eine beliebige Anzahl von Fragen.

            PHP-Code:
            <?php

            return array(
                array(
                    
            'text' => 'Welches Tier wird als „bester Freund des Menschen“ bezeichnet?',
                    
            'answers' => array('Hund''Katze''Maus''Schwein'),
                    
            'correct_answer' => 0
                
            ),
                array(
                    
            'text' => 'Welche Farbe ist bei einem Regenbogen oben?',
                    
            'answers' => array('Rot''Grün''Blau''Gelb'),
                    
            'correct_answer' => 0
                
            ),
                array(
                    
            'text' => 'Welches ist die Hauptstadt von Assyrien?',
                    
            'answers' => array('Persepolis''Karthago''Alexandria''Ninive'),
                    
            'correct_answer' => 3
                
            )
            );
            src/shared.php

            Gemeinsam genutzte Funktionen (als Closures angelegt, können aber auch echte Funktionen sein).

            PHP-Code:
            <?php

            $e 
            = function ($s) {
                return 
            htmlspecialchars(
                    
            $s,
                    
            ENT_QUOTES ENT_HTML5 ENT_DISALLOWED ENT_SUBSTITUTE,
                    
            'UTF-8'
                
            );
            };

            $makeQuestionFileName = function ($index) {
                return 
            sprintf('question%s.php'$index);
            };
            src/index.php

            Die Willkommensseite. Hier werden die Session-Daten auf einen Startzustand gesetzt. Zudem existiert ein Link zur ersten Frage.

            PHP-Code:
            <?php

            require __DIR__ '/shared.php';

            session_start();

            $_SESSION = array();
            $_SESSION['current_question'] = 0;
            $_SESSION['answers'] = array();

            header('Content-Type: text/html; charset=UTF-8');

            ?>

            <h1>Quiz</h1>

            <p><a href="<?=$e($makeQuestionFileName(0))?>">Start</a></p>
            src/auswertung.php

            Hier werden die Antworten auf die Fragen, die sukzessive in der Session gespeichert werden, schließlich ausgewertet.

            PHP-Code:
            <?php

            require __DIR__ '/shared.php';

            $questions = require __DIR__ '/questions.php';

            session_start();

            $answers $_SESSION['answers'];

            header('Content-Type: text/html; charset=UTF-8');

            ?>

            <h1>Auswertung</h1>

            <?php foreach ($questions as $question_index => $question) : ?>

                <p><?=$e($question['text'])?></p>
                <p>Richtige Antwort: <?=$e($question['answers'][$question['correct_answer']])?></p>
                <p>Ihre Antwort: <?=$e($question['answers'][$answers[$question_index]])?></p>
                <hr>

            <?php endforeach; ?>

            <p>Danke fürs Spielen.</p>

            <p><a href="index.php">Wiederholen</a></p>
            src/question.template.php

            Hier wird jeweils eine Frage gestellt und die Antwort dazu gespeichert. Wurde die letzte Frage gestellt, wird nach dem Speichern der Antwort nicht zur nächsten Frage weitergeleitet, sondern zur Auswertungsseite.

            Eine Kopie dieser Datei wird für jede Frage einmal mit eindeutigem Namen angelegt. Dazu gleich mehr.

            PHP-Code:
            <?php

            require __DIR__ '/shared.php';

            $questions = require __DIR__ '/questions.php';

            session_start();

            if (isset(
            $_POST['action'])) {
                if (
            $_POST['action'] === 'answer') {
                    
            $_SESSION['answers'][$_POST['question_index']] = $_POST['answer_index'];
                    
            $_SESSION['current_question']++;

                    
            $url = ($_SESSION['current_question'] === count($questions))
                            ? 
            'auswertung.php'
                            
            $makeQuestionFileName($_SESSION['current_question']);
                    
            header('Location: ' $url);
                    exit;
                }
            }

            $tpl = array(
                
            'question'       => $questions[$_SESSION['current_question']],
                
            'question_index' => $_SESSION['current_question'],
                
            'target_file'    => $makeQuestionFileName($_SESSION['current_question'])
            );

            header('Content-Type: text/html; charset=UTF-8');

            ?>

            <form method="post" action="<?=$e($tpl['target_file'])?>">
                <p><?=$e($tpl['question']['text'])?></p>

                <?php $first true?>
                <?php foreach ($tpl['question']['answers'] as $index => $text) : ?>
                    <?php $checked = ($first) ? ' checked="checked"' ''$first false?>
                    <p><input type="radio" name="answer_index" value="<?=$e($index)?>"<?=$checked?>><?=$e($text)?></p>
                <?php endforeach; ?>

                <p>
                    <input type="hidden" name="question_index" value="<?=$e($tpl['question_index'])?>">
                    <input type="hidden" name="action" value="answer">
                    <input type="submit" value="Senden">
                </p>
            </form>
            generate.php

            Da für jede Frage eine einzelne Datei existieren soll, habe ich ein kleines Build-Script geschrieben, das auf Grundlage der Dateien in "src" eine fertige Version des Projekts in "output" erstellt.

            Das Script ist sehr simpel. Es kopiert alle Dateien außer "question.template.php" einfach von "src" nach "output". Die Datei "question.template.php" wird mehrfach kopiert (für jede Frage einmal), wobei die Dateien fortlaufend benannt werden.

            PHP-Code:
            <?php

            $outputDir 
            __DIR__ '/output';
            $sourceDir __DIR__ '/src';

            require 
            $sourceDir '/shared.php';

            $questions = require $sourceDir '/questions.php';

            $copy = array(
                
            'auswertung.php',
                
            'index.php',
                
            'questions.php',
                
            'shared.php'
            );

            foreach (
            $copy as $file) {
                
            copy(
                    
            $sourceDir '/' $file,
                    
            $outputDir '/' $file
                
            );
            }

            for (
            $i 0$i count($questions); $i++) {
                
            copy(
                    
            $sourceDir '/question.template.php',
                    
            $outputDir '/' $makeQuestionFileName($i)
                );
            }
            Das Script kann per Konsole $ php -f generate.php ausgeführt werden, kann aber auch über den Browser aufgerufen werden. Entsprechende Schreibrechte für das "output"-Verzeichnis müssen natürlich existieren. Zudem bietet es sich an, die Inhalte in "output" vor dem Generieren zumindest dann zu löschen, wenn die Anzahl der Fragen verringert wird. Sonst bleiben ungenutzte Dateien zurück.

            Nach der Generierung sieht das gesamte Projektverzeichnis in etwa so aus:

            Code:
            .
            |-- generate.php
            |-- output
            |   |-- auswertung.php
            |   |-- index.php
            |   |-- question0.php
            |   |-- question1.php
            |   |-- question2.php
            |   |-- questions.php
            |   `-- shared.php
            `-- src
                |-- auswertung.php
                |-- index.php
                |-- questions.php
                |-- question.template.php
                `-- shared.php
            Der Inhalt von "output" kann nun an einen beliebigen Ort kopiert werden. Das ist die vollständige Anwendung. Sie kann durch Anwählen von "output/index.php" natürlich auch getestet werden.

            Bei Veränderungen an den "src"-Dateien einfach die Ausgabe neu generieren. Beim Hinzufügen weiterer Dateien in "src" (CSS-Datei oder so) die entsprechenden Dateinamen auch in generate.php einfügen, damit sie beim Generieren auch kopiert werden.

            Was zum Beispiel noch fehlt:

            - Fehlerbehandlung (etwa für unvollständige oder falsche POST-Daten oder für Direktaufruf einer Fragenseite oder von auswertung.php, ohne über index.php und die vorherigen Fragen gegangen zu sein)
            - korrektes HTML-Gerüst (head, body usw.)
            - hübschere Auswertung, die unter anderem die Anzahl richtiger Antworten ermittelt

            Da das Build-Script Dateien erstellt und gegebenenfalls überschreibt, sage ich noch dazu: Nutzung natürlich auf eigene Gefahr, auch wenn ich es nach bestem Wissen und Gewissen programmiert habe und sich alle Operationen auf das "output"-Verzeichnis beziehen sollten.

            PS: Ich habe das primär deshalb geschrieben, um in jede der einzelnen Fragendateien exakt den gleichen Inhalt zu setzen. Ich hoffe, die Ironie ist nicht verloren.

            PPS: Noch mehr Spaß:

            PHP-Code:
            $makeQuestionFileName = function ($index) {
                
            //return sprintf('question%s.php', $index);
                
            return md5($index) . '.php';
            }; 
            (Die Funktion muss lediglich einen gültigen, eindeutigen Dateinamen zurückliefern. Sie muss injektiv sein. md5() ist das zwar eigentlich nicht, aber für die ersten paar Milliarden Fragen wird es wohl reichen.)

            Kommentar

            Lädt...
            X