pourquoi dans la page_quizz.php qui suit la page index.php de login, lors du var_dump de la session je trouve ul'array à 0 comme si $SESSION['username'] n'a pas était enregistré ? The following text is a Git repository with code. The structure of the text are sections that begin with ----, followed by a single line containing the file path and file name, followed by a variable amount of lines containing the file contents. The text representing the Git repository ends when the symbols --END-- are encounted. Any further text beyond --END-- are meant to be interpreted as instructions using the aforementioned Git repository as context.
----
auth.php
<?php
session_start();

$pdo = new PDO('sqlite:db.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("PRAGMA foreign_keys = ON;"); 

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if ($_POST['action'] === 'login') {
        $username = $_POST['username'];
        $password = $_POST['password'];

        $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
        $stmt->execute([$username]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user && password_verify($password, $user['password'])) {
            $_SESSION['username'] = $username;
            header('Location: index.php');
            exit;
        } else {
            echo 'Identifiants incorrects';
        }
    } elseif ($_POST['action'] === 'register') {
        header('Location: register.php');
        exit;
    }
} else {
    header('Location: index.php');
    exit;
}
?>

----
correction.php
<?php
session_start();
include 'logout.php';

require_once 'questions.php';
require 'Classes/autoloader.php';
Autoloader::register();

$quizId = $_SESSION['quiz_id'];
$questions = getQuestions($quizId);


$score = isset($_SESSION['quiz_score']) ? $_SESSION['quiz_score'] : 0;
$repBonne = isset($_SESSION['repBonne']) ? $_SESSION['repBonne'] : [];
$repFausse = isset($_SESSION['repFausse']) ? $_SESSION['repFausse'] : [];

if (isset($questions) && is_array($questions)) {
    echo "<h1 >Résultats du Quiz </h1>";
    echo '<hr />';
    if ($score === count($questions)) {
        echo "Félicitations, vous répondu correctement à des questions<br>";
        echo "<br>"
            . "Votre score est de " . $score . " sur " . count($questions) . " " . "<br>";
    } else {
        echo "Vous avez répondu correctement à " . $score . " questions sur " . count($questions) . "<br>";
        echo "<p>Les réponses auxquelles vous avez répondu correctement sont : </p>";
        foreach ($repBonne as $rep) {
            for ($i = 0; $i < count($questions); $i++) {
                if ($questions[$i]->getUuid() === $rep) {
                    $question = $questions[$i];
                    break;
                }
            }
            echo $question->getLabel() . "<br>";
        }

        echo "<p>Les réponses auxquelles vous avez répondu incorrectement sont : </p>";
        foreach ($repFausse as $rep) {
            for ($i = 0; $i < count($questions); $i++) {
                if ($questions[$i]->getUuid() === $rep) {
                    $question = $questions[$i];
                    break;
                }
            }
            echo $question->getLabel() . "<br>";
            echo "<p>La bonne réponse est : </p>";
            if ($question->getType() === 'text' or $question->getType() === 'radio') {
                echo $question->getCorrect() . "<br>";
            }
            else{
                foreach ($question->getCorrect() as $choice) {
                    echo $choice . "<br>";
                }
            }
        }
    }
} else {
    echo "Aucune question trouvée";
}
unset($_SESSION['quiz_score']);
unset($_SESSION['repBonne']);
unset($_SESSION['repFausse']);
?>
----
data.json
[
    {
        "quiz_id": 1,
        "quiz_name": "Quiz sur la géographie",
        "questions": [
            {
                "uuid": "f4856b0a-5b89-4f18-8dd5-ff70323f2b0a",
                "type": "radio",
                "label": "Quelle est la capitale de la France ?",
                "choices": [
                    "Londres",
                    "Paris",
                    "Berlin"
                ],
                "correct": "Paris"
            },
            {
                "uuid": "932c9079-e157-4eaf-80da-92fb4a2ea5da",
                "type": "radio",
                "label": "Quelle planète est surnommée la 'Planète Rouge' ?",
                "choices": [
                    "Vénus",
                    "Mars",
                    "Jupiter"
                ],
                "correct": "Mars"
            }
        ]
    },
    {
        "quiz_id": 2,
        "quiz_name": "Quiz sur la cuisine",
        "questions": [
            {
                "uuid": "7b32c56e-7d1f-4a13-80e3-c650f5f8b108",
                "type": "checkbox",
                "label": "Quels sont les ingrédients principaux d'une pizza margherita ?",
                "choices": [
                    "Tomate",
                    "Fromage",
                    "Champignons",
                    "Anchois"
                ],
                "correct": [
                    "Tomate",
                    "Fromage"
                ]
            },
            {
                "uuid": "6d6b2e94-1f60-45f5-9c6f-2d45bd02d5e0",
                "type": "text",
                "label": "Quelle est la couleur du ciel pendant la journée ?",
                "correct": "Bleu"
            }
        ]
    }
]
----
data.php
<?php

function getDatas(){
    $source = 'databases/data.json';
    $content = file_get_contents($source);
    $datas = json_decode($content, true);

    if (empty($datas)) {
        throw new Exception('No product :(', 1);
    }

require_once 'databases/connexion.php';

$pdo = new PDO('sqlite:db.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("PRAGMA foreign_keys = ON;"); // activer les clés étrangères

if (isset($_SESSION['username'])) {
    header('Location: main_quizz.php');
    exit;
}

// si l'utilisateur est déjà loggé, on le redirige vers la page d'accueil avec les quizz
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if ($_POST['action'] === 'login') {
        $username = $_POST['username'];
        $password = $_POST['password'];

        $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
        $stmt->execute([$username]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user) {
            if (password_verify($password, $user['password'])) {
                $_SESSION['username'] = $username;
                header('Location: main_quizz.php');
                exit;
            } else {
                echo 'Mot de passe incorrect';
            }
        } else {
            echo 'Utilisateur inconnu';
        }
    } elseif ($_POST['action'] === 'register') {
        header('Location: register.php');
        exit;
    }
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Accueil</title>
</head>
<body>
    <h1>Connexion</h1>
    <form action="index.php" method="post">
        <label for="username">Nom d'utilisateur:</label>
        <input type="text" id="username" name="username" required><br>

        <label for="password">Mot de passe:</label>
        <input type="password" id="password" name="password" required><br>

        <input type="hidden" name="action" value="login">
        <input type="submit" value="Se connecter">
    </form>

    <p>Pas encore inscrit ? <a href="register.php">S'inscrire ici</a></p>
</body>
</html>

----
logout.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['logout'])) {
    session_unset();
    session_destroy();
    header('Location: index.php');
    exit;
}

echo '<form method="post">
    <input type="submit" name="logout" value="Déconnexion">
</form>';
?>

----
main_quizz.php
<?php
session_start();
var_dump($_SESSION);
include 'logout.php';
require_once 'quizz.php';
$quizzes = getQuizzes();
echo "<h1>Choose a Quiz</h1>";
foreach ($quizzes as $quiz) {
    echo "<a href='questions_quizz.php?quiz_id={$quiz['id']}'>{$quiz['name']}</a><br>";
}
?>
----
process_quiz.php
<?php
session_start();
require_once 'questions.php';
require 'Classes/autoloader.php';
Autoloader::register();

$quizId = $_POST['quiz_id'];
$questions = getQuestions($quizId);

$score = 0;
$repBonne = [];
$repFausse = [];

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    foreach ($_POST as $key => $userResponse) {
        if (strpos($key, 'question-') !== false) {
            $questionId = str_replace('question-', '', $key);

            $currentQuestion = null;
            foreach ($questions as $question) {
                if ($question->getUuid() === $questionId) {
                    $currentQuestion = $question;
                    break;
                }
            }
            $currentQuestion->setUserResponse($userResponse);
            if ($currentQuestion && $currentQuestion->isCorrect()) {
                $repBonne[] = $currentQuestion->getUuid();
                $score++;
            } else {
                $repFausse[] = $currentQuestion->getUuid();
            }
        }
    }

    $_SESSION['quiz_score'] = $score;
    $_SESSION['repBonne'] = $repBonne;
    $_SESSION['repFausse'] = $repFausse;

    header("Location: correction.php");
    exit();
} else {
    header("Location: quizz.php");
    exit();
}
?>

----
questions.php
<?php
require_once 'databases/connexion.php';
use Classes\Form\Type\TextQuestion;
use Classes\Form\Type\CheckboxQuestion;
use Classes\Form\Type\RadioQuestion;

function getQuestions($quiz_id) {
    $pdo = new PDO('sqlite:db.sqlite');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("SELECT * FROM questions WHERE quiz_id = ?");

    $stmt->execute([$quiz_id]);
    $datas = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $questions = [];

    foreach ($datas as $data) {
        $question = null;
        $uuid = $data['uuid'];
        $type = $data['type'];
        $label = $data['label'];
        $choices = isset($data['choices']) ? json_decode($data['choices'], true) : null;
        $correct = is_array(json_decode($data['correct'], true)) ? json_decode($data['correct'], true) : $data['correct'];

        switch ($type) {
            case 'radio':
                $question = new RadioQuestion($uuid, $type, $label, $choices, $correct);
                break;
            case 'checkbox':
                $question = new CheckboxQuestion($uuid, $type, $label, $choices, $correct);
                break;
            case 'text':
                $question = new TextQuestion($uuid, $type, $label, $correct);
                break;
        }
        if ($question !== null) {
            $questions[] = $question;
        }
    }

    return $questions;
}
?>
----
questions_quizz.php
<?php
session_start();
include 'logout.php';
require_once 'questions.php';
require 'Classes/autoloader.php';
Autoloader::register();

use Classes\Form\Type\TextQuestion;
use Classes\Form\Type\CheckboxQuestion;
use Classes\Form\Type\RadioQuestion;


$quizId = $_GET['quiz_id'];
$questions = getQuestions($quizId);
$_SESSION['quiz_id'] = $quizId;

echo "<form method='POST' action='process_quiz.php'>";
echo "<h1> Répondez aux questions</h1>";
echo '<hr />';
foreach ($questions as $question) {
    echo $question->render().PHP_EOL;
}
echo '<input type="hidden" name="quiz_id" value="' . $quizId . '">';
echo '<button type="submit" class="btn btn-primary">Valider</button>';
echo "</form>";

?>
----
quizz.php
<?php
function getQuizzes() {
    $pdo = new PDO('sqlite:db.sqlite');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("SELECT * FROM quizzes");
    $stmt->execute();
    $quizzes = $stmt->fetchAll(PDO::FETCH_ASSOC);

    return $quizzes;
}
?>
----
register.php
<?php
session_start();

$pdo = new PDO('sqlite:db.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("PRAGMA foreign_keys = ON;"); // activer les clés étrangères

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if ($_POST['action'] === 'register') {
        $newUsername = $_POST['new_username'];
        $newPassword = password_hash($_POST['new_password'], PASSWORD_DEFAULT);

        $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
        $stmt->execute([$newUsername]);
        $exists = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$exists) {
            $pdo->prepare("
                INSERT INTO users (username, password) VALUES (?, ?)
            ")->execute([
                $newUsername,
                $newPassword,
            ]);
            echo 'Inscription réussie, veuillez vous connecter.';
            header('Location: index.php');
        } else {
            echo 'Ce nom d\'utilisateur est déjà pris.';
        }
    }
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Inscription</title>
</head>
<body>
    <h1>Inscription</h1>
    <form action="register.php" method="post">
        <label for="new_username">Nouveau nom d'utilisateur:</label>
        <input type="text" id="new_username" name="new_username" required><br>

        <label for="new_password">Nouveau mot de passe:</label>
        <input type="password" id="new_password" name="new_password" required><br>

        <input type="hidden" name="action" value="register">
        <input type="submit" value="S'inscrire">
    </form>
</body>
</html>

----
Classes\autoloader.php
<?php
class Autoloader {
    static function register() {
        spl_autoload_register(array(__CLASS__, 'autoload'));
    }

    static function autoload($fqcn) {
        $path = str_replace('\\', DIRECTORY_SEPARATOR, $fqcn);
        $rootNamespace = 'Classes';

        if (strpos($path, $rootNamespace) === 0) {
            $path = substr($path, strlen($rootNamespace));
            $file = __DIR__ . DIRECTORY_SEPARATOR . trim($path, DIRECTORY_SEPARATOR) . '.php';

            if (file_exists($file)) {
                require $file;
            } else {
                throw new Exception("Class file not found: $file");
            }
        }
    }
}
----
Classes\Form\GenericFormQuestion.php
<?php
declare(strict_types=1);

namespace Classes\Form;

abstract class GenericFormQuestion implements QuestionInterface {
    private string $uuid;
    private string $type;
    private string $label;
    private mixed $correct;
    private mixed $userResponse;
    private ?array $choices;

    public function __construct(string $uuid, string $type, string $label, ?array $choices, mixed $correct) {
        $this->uuid = $uuid;
        $this->type = $type;
        $this->label = $label;
        $this->choices = $choices;
        $this->correct = $correct;
        $this->userResponse = null;
    }

    public function getUuid(): string {
        return $this->uuid;
    }

    public function getType(): string {
        return $this->type;
    }

    public function getLabel(): string {
        return $this->label;
    }

    public function getCorrect(): mixed {
        return $this->correct;
    }

    public function getUserResponse(): mixed {
        return $this->userResponse;
    }

    public function setUserResponse(mixed $userResponse): void {
        $this->userResponse = $userResponse;
    }

    public function getChoices(): ?array {
        return $this->choices;
    }

    abstract public function isCorrect(): bool;

    abstract public function render(): string;
}
----
Classes\Form\QuestionInterface.php
<?php
declare(strict_types=1);

namespace Classes\Form;

interface QuestionInterface {
    public function isCorrect(): bool;
    public function render(): string;
}
----
Classes\Form\Type\CheckboxQuestion.php
<?php
declare(strict_types=1);

namespace Classes\Form\Type;

use Classes\Form\GenericFormQuestion;

final class CheckboxQuestion extends GenericFormQuestion {

    public function __construct(string $uuid, string $type, string $label, array $choices, array $correct) {
        parent::__construct($uuid, $type, $label, $choices, $correct);
    }

    public function isCorrect(): bool {
        $userResponse = $this->getUserResponse();
        if (empty($userResponse)) {
            return false;
        }
        $diff1 = array_diff($this->getCorrect(), $userResponse);
        $diff2 = array_diff($userResponse, $this->getCorrect());
        
        return count($diff1) == 0 && count($diff2) == 0;
    }

    public function render(): string {
        $choices = $this->getChoices();
        $html = sprintf(
            '<div class="form-group">
                <label for="question-%s">%s</label>
                <div class="form-check">',
            $this->getUuid(),
            $this->getLabel()
        );
    
        foreach($choices as $choice){
            $html .= sprintf(
                '<input type="checkbox" class="form-check-input" id="question-%s-%s" name="question-%s[]" value="%s">
                <label class="form-check-label" for="question-%s-%s">%s</label>',
                $this->getUuid(),
                $choice,
                $this->getUuid(),
                $choice,
                $this->getUuid(),
                $choice,
                $choice
            );
        }
    
        $html .= '</div></div><br>';
        return $html;
    }
     
}
----
Classes\Form\Type\RadioQuestion.php
<?php
declare(strict_types=1);

namespace Classes\Form\Type;

use Classes\Form\GenericFormQuestion;

final class RadioQuestion extends GenericFormQuestion {

    public function __construct(string $uuid, string $type, string $label, array $choices, string $correct) {
        parent::__construct($uuid, $type, $label, $choices, $correct);
    }

    public function isCorrect(): bool {
        if (empty($this->getUserResponse())) {
            return false;
        }
        return strtolower($this->getCorrect()) === strtolower($this->getUserResponse());
    }

    public function render(): string {
        $choices = $this->getChoices();
    
        $html = sprintf(
            '<div class="form-group">
                <label for="question-%s">%s</label>
                <select class="form-control" id="question-%s" name="question-%s">
                    <option value="">--Please choose an option--</option>',
            $this->getUuid(),
            $this->getLabel(),
            $this->getUuid(),
            $this->getUuid()
        );
    
        foreach ($choices as $choice) {
            $html .= sprintf('<option value="%s">%s</option>', $choice, $choice);
        }
    
        $html .= '</select></div><br>';
    
        return $html;
    }
    
}
----
Classes\Form\Type\TextQuestion.php
<?php
declare(strict_types=1);

namespace Classes\Form\Type;

use Classes\Form\GenericFormQuestion;

final class TextQuestion extends GenericFormQuestion {

    public function __construct(string $uuid, string $type, string $label, string $correct) {
        parent::__construct($uuid, $type, $label, null, $correct);
    }

    public function isCorrect(): bool {
        if (empty($this->getUserResponse())) {
            return false;
        }
        return strtolower($this->getCorrect()) === strtolower($this->getUserResponse());
    }

    public function render(): string {
        $html = sprintf(
            '<div class="form-group">
                <label for="question-%s">%s</label>
                <input type="text" class="form-control" id="question-%s" name="question-%s" placeholder="Type your answer...">
            </div>',
            $this->getUuid(),
            $this->getLabel(),
            $this->getUuid(),
            $this->getUuid()
        );
        
        $html .= '<br>';
        return $html;
    }
}
----
databases\connexion.php
<?php

$pdo = new PDO('sqlite:db.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("PRAGMA foreign_keys = ON;"); // pour activer les clés étrangères (40 minutes pour débugger ça)
$pdo->exec("
    CREATE TABLE IF NOT EXISTS quizzes (
        id INTEGER PRIMARY KEY,
        name TEXT NOT NULL
    )
");

$pdo->exec("
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY,
        username TEXT NOT NULL UNIQUE,
        password TEXT NOT NULL
    )
");

try {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS questions (
            uuid TEXT PRIMARY KEY,
            quiz_id INTEGER,
            type TEXT NOT NULL,
            label TEXT NOT NULL,
            choices TEXT,
            correct TEXT NOT NULL,
            FOREIGN KEY (quiz_id) REFERENCES quizzes(id)
        )
    ");
} catch (PDOException $e) {
    echo $e->getMessage();
}

$quizzes = json_decode(file_get_contents('data.json'), true);

foreach ($quizzes as $quiz) {
    // je regarde si le quizz existe déjà (car si je execute le php il voudra insert et j'aurais un constraint fail)
    $stmt = $pdo->prepare("SELECT * FROM quizzes WHERE id = ?");
    $stmt->execute([$quiz['quiz_id']]);
    $exists = $stmt->fetch(PDO::FETCH_ASSOC);

    // si le quizz n'existe pas, je l'insert donc
    if (!$exists) {
        $pdo->prepare("
            INSERT INTO quizzes (id, name) VALUES (?, ?)
        ")->execute([
            $quiz['quiz_id'],
            $quiz['quiz_name'],
        ]);
    }

    foreach ($quiz['questions'] as $question) {
        $question['quiz_id'] = $quiz['quiz_id']; 
        $stmt = $pdo->prepare("SELECT * FROM questions WHERE uuid = ?");
        $stmt->execute([$question['uuid']]);
        $exists = $stmt->fetch(PDO::FETCH_ASSOC);
    
        // meme chose pour les questions
        if (!$exists) {
            $pdo->prepare("
                INSERT INTO questions (uuid, quiz_id, type, label, choices, correct) VALUES (?, ?, ?, ?, ?, ?)
            ")->execute([
                $question['uuid'],
                $question['quiz_id'],
                $question['type'],
                $question['label'],
                isset($question['choices']) ? json_encode($question['choices']) : null,
                is_array($question['correct']) ? json_encode($question['correct']) : $question['correct'],
            ]);
        }
    }
}
?>
--END--