Hello,
a quiz was also one of my first projects but your codes are much better than mine were: I didn't know anything about OO and all the code was just copy and pasted. :)
Regarding Village Idiot's proposal: I never let my classes output anything unless it's explicitly wished (e.g. in template engines). I think classes should be portable meaning you can use them in different types of applications (console, PHP-Gtk applications, websites, etc.) and output (SOAP, XML-RPC, HTML, etc.). The advantage is that we don't need to change the basic class, only the code for the generation of the output.
Back to topic: If you have many questions it might be better to store them in a database. Anyway, I came up with a PHP-only solution. It's just an idea for an implementation since I didn't have the time to write the code.
PHP Code:
<?php
//we create an instance of the class "Question" for every question
$question0 = new Question();
$question0->setQuestion('What is the best language?'); //string $question
$question0->addAnswer('English', true); //string $answer, boolean $correct
$question0->addAnswer('French', true);
$question0->addAnswer('Spanish', true);
$question0->addAnswer('German', false);
$question1 = new Question();
$question1->setQuestion('What is the best scripting language?');
$question1->addAnswer('PHP', true);
$question1->addAnswer('Ruby', false);
$question1->addAnswer('Python', false);
//add more questions...
//"Questions" is a stack of questions which might be stored internally in an array
$stack = new Questions();
//now we'll add all previously created questions to the 'stack'
$stack->addQuestion($question0); //object $question
$stack->addQuestion($question1);
if (isset($_POST['answers']) && is_array($_POST['answers']) && (count($_POST['answers'] > 0)) {
//we need to set all client's answers
//attention: you need to check if the keys really do exist otherwise you'll get some warnings by PHP unless you're not supressing them (e.g. by error_reporting(0))
$question0->setUserAnswer($_POST['answers'][0]);
$question1->setUserAnswer($_POST['answers'][1]);
//even better would be to iterate over $_POST['answers'] because you don't have to set the answers manually
//very important - the client could have modified the keys, so we reindex the array
$_POST['answers'] = array_values($_POST['answers']);
foreach ($_POST['answers'] as $num => $answer) {
if (isset(${'question' . $num})) { //we check if that variable does really exist
${'question' . $num}->setUserAnswer($answer);
}
}
//now we'll check the input
foreach ($stack->checkAnswers() as $question) { //$question is an instance of the class "Question" which we used above
echo 'Question: ' . $question->getQuestion() . '<br />' . PHP_EOL;
foreach ($question->getAnswers() as $answer) { //$answer is an instance of the class "Answer"
echo 'Answer: ' . $answer->getText() . ' (' . ($answer->isCorrect() ? 'correct' : 'wrong') . ')<br />' . PHP_EOL;
echo 'Your input was ' . ($answer->isUserInputCorrect() ? 'correct' : 'wrong') . '<br />' . PHP_EOL;
echo '<br />' . PHP_EOL;
//here we could do things like increasing a variable to get the number of corrected answered questions
}
echo '<hr />';
}
} else {
//now we'll generate the form
foreach ($stack->getQuestions() as $question) {
//echo the input fields
//...
}
}
So here's a short summary of all classes I used:
Answer
+ getText() : string
+ isCorrect() : string
+ isUserInputCorrect() : boolean
Question
+ setQuestion(string $question) : void
+ getQuestion() : string
+ getAnswers() : array
+ addAnswer(string $answer, boolean $correct) : void
+ setUserAnswer(string $answer) : void
Questions
+ addQuestion(Question $question) : void
+ checkAnswers() : array
+ getQuestions() : array