Home >Backend Development >PHP Tutorial >Practical OOP: Building a Quiz App - MVC

Practical OOP: Building a Quiz App - MVC

Jennifer Aniston
Jennifer AnistonOriginal
2025-02-19 10:40:09711browse

Practical OOP: Building a Quiz App - MVC

This tutorial continues building a quiz application using a bottom-up design approach and the MVC (Model-View-Controller) pattern. Part one covered the creation of Quiz and Question entities, a placeholder Data Mapper, and the service interface. This part focuses on implementing the service, controllers, and views using the Slim framework, and finally, replacing the dummy mapper with a MongoDB-based one.

Key Concepts:

  • MVC Architecture: The application uses the Model-View-Controller pattern, with the Quiz and Question entities forming the Model, the user interface as the View, and the Quiz service defining the user interaction flow (Controller).
  • Slim Framework: Slim provides the framework for controllers and views. Its modularity allows for easy replacement with other MVC frameworks.
  • Data Access: A data mapper connects to MongoDB, abstracting database interactions. This allows for easy database switching.
  • Service Layer and Domain Model: The application employs a service layer to encapsulate business logic, adhering to the "fat model, thin controller" principle for maintainability.
  • Implementation Agnosticism: The service is designed to be independent of the user interface, allowing for different front-ends (e.g., command-line).

Service Implementation (QuizAppServiceQuiz)

The core service class (QuizAppServiceQuiz) is detailed below. Note that session variables are used for simplicity; a more robust solution would use a dedicated session management layer for broader application contexts.

<code class="language-php"><?php
namespace QuizApp\Service;

use QuizApp\Service\Quiz\Result;

// ...

class Quiz implements QuizInterface
{
    // ... (constants remain the same)

    // ... (constructor remains the same)

    // ... (showAllQuizes remains the same)

    public function startQuiz($quizOrId)
    {
        // ... (logic remains largely the same)
    }

    // ... (getQuestion remains largely the same)

    public function checkSolution($solutionId)
    {
        // ... (logic remains largely the same)
    }

    // ... (isOver remains largely the same)

    // ... (getResult remains the same)

    // ... (getCurrentQuiz remains largely the same)

    // ... (getCurrentQuestionId remains the same)

    // ... (addResult remains the same)
}</code>

The code for showAllQuizes, startQuiz, getQuestion, checkSolution, isOver, getResult, getCurrentQuiz, getCurrentQuestionId, and addResult methods remains largely unchanged from the original, focusing on core functionality.

Slim Framework Integration

The Slim application is initialized in index.php, setting up routing and rendering.

<code class="language-php"><?php
require 'vendor/autoload.php';

session_start();

$service = new \QuizApp\Service\Quiz(
    new \QuizApp\Mapper\HardCoded() //Initially using HardCoded mapper
);
$app = new \Slim\Slim();
$app->config(['templates.path' => './views']);

// Routes (simplified for brevity)
$app->get('/', function () use ($service, $app) {
    $app->render('choose-quiz.phtml', ['quizes' => $service->showAllQuizes()]);
});

$app->get('/choose-quiz/:id', function ($id) use ($service, $app) {
    $service->startQuiz($id);
    $app->redirect('/solve-question');
});

$app->get('/solve-question', function () use ($service, $app) {
    $app->render('solve-question.phtml', ['question' => $service->getQuestion()]);
});

$app->post('/check-answer', function () use ($service, $app) {
    $isCorrect = $service->checkSolution($app->request->post('id'));
    // ... (redirect logic remains the same)
});

$app->get('/end', function () use ($service, $app) {
    $app->render('end.phtml', ['result' => $service->getResult()]);
});

$app->run();</code>

The views (choose-quiz.phtml, solve-question.phtml, end.phtml) remain largely the same, handling the presentation of data.

MongoDB Mapper (QuizAppMapperMongo)

The Mongo mapper interacts with a MongoDB collection. Error handling and more robust data validation should be added for production use.

<code class="language-php"><?php
namespace QuizApp\Service;

use QuizApp\Service\Quiz\Result;

// ...

class Quiz implements QuizInterface
{
    // ... (constants remain the same)

    // ... (constructor remains the same)

    // ... (showAllQuizes remains the same)

    public function startQuiz($quizOrId)
    {
        // ... (logic remains largely the same)
    }

    // ... (getQuestion remains largely the same)

    public function checkSolution($solutionId)
    {
        // ... (logic remains largely the same)
    }

    // ... (isOver remains largely the same)

    // ... (getResult remains the same)

    // ... (getCurrentQuiz remains largely the same)

    // ... (getCurrentQuestionId remains the same)

    // ... (addResult remains the same)
}</code>

Remember to replace the HardCoded mapper instance in index.php with the Mongo mapper once the MongoDB setup is complete. The rowToEntity method handles the conversion of database rows into Quiz and Question objects.

The conclusion and FAQs remain largely the same, emphasizing the benefits of the MVC pattern, Slim framework, and service layer design. The code examples are simplified for clarity. Complete, production-ready code would require more comprehensive error handling, input validation, and security measures.

The above is the detailed content of Practical OOP: Building a Quiz App - MVC. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn