Retour aux projets // Application de Chat Web
💬

Application de Chat Web

Plateforme de messagerie en temps réel avec salons de discussion, authentification utilisateurs et stockage JSON. Interface gaming avec design néon, système de salons et admin.

PHPJSONCSS TailwindCSSSessionsAuth

Description

Application de messagerie développée en PHP pur avec stockage JSON (pas de base de données SQL). Les utilisateurs s'inscrivent, se connectent, créent des salons et envoient des messages. Un panneau admin permet de gérer les utilisateurs. L'interface adopte un style gaming avec effets néon.

Fonctionnalités

🔐

Authentification

Inscription, connexion, sessions PHP sécurisées avec password_hash

💬

Salons de chat

Création de salons nommés, messagerie persistante par salon

🗄️

Stockage JSON

userdb.json, messagedb.json, salondb.json — pas de BDD SQL

🎮

Design Gaming

Interface néon cyberpunk avec effets blur et gradients animés

👑

Panneau Admin

Gestion des utilisateurs, consultation des messages

🏗️

Architecture OOP

Classes User, Message, Salon, JsonDb avec héritage

Architecture

login.php
→
salon_a.php
→
chat.php?salonId=X
register.php
→
Userdb.php
→
userdb.json
message.php
→
MessageDb.php
→
messagedb.json

Code source

salon_a.php
chat.php
JsonDb.php
login.php
salon_a.php — Interface gaming d'entrée
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once 'JsonObject.php';
require_once 'SalonDb.php';

$salonCree = null;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $nom = $_POST['name'] ?? '';
    if (!empty($nom)) {
        $salonDb = SalonDb::load();
        $salonCree = Salon::create($nom);
        $salonDb->insert($salonCree);
        $salonDb->save();
        header("Location: chat.php?salonId=" . $salonCree->id);
        exit;
    }
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Salon - Entrée au Lobby</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Rajdhani:wght@400;600&display=swap" rel="stylesheet">
    <style>
        body { background: radial-gradient(circle at center, #1a1c2c 0%, #0a0b14 100%); }
        .gaming-card {
            background: rgba(255,255,255,0.03);
            backdrop-filter: blur(15px);
            border: 1px solid rgba(255,255,255,0.1);
            border-top: 3px solid #00f2ff;
            box-shadow: 0 0 30px rgba(0,242,255,0.15);
        }
        .neon-text { font-family:'Orbitron',sans-serif; text-shadow: 0 0 10px rgba(0,242,255,0.7); }
        .btn-ready {
            background: linear-gradient(90deg, #00f2ff, #7000ff);
            text-transform: uppercase;
            letter-spacing: 2px;
            transition: all 0.3s;
        }
        .btn-ready:hover { filter: brightness(1.2); transform: scale(1.02); }
    </style>
</head>
<body class="flex items-center justify-center min-h-screen">
    <div class="gaming-card p-10 rounded-2xl w-full max-w-md">
        <header class="text-center mb-8">
            <h1 class="neon-text text-3xl font-bold text-cyan-400">SALON D'ENTRÉE</h1>
        </header>
        <form method="POST" class="space-y-6">
            <input type="email" name="email" placeholder="Tag Joueur (Email)" required>
            <input type="password" name="password" placeholder="Clé d'accès" required>
            <input type="text" name="name" placeholder="Nom du salon" required>
            <button type="submit" class="btn-ready w-full py-4 rounded-lg font-bold text-white">
                Déployer la session
            </button>
        </form>
    </div>
</body>
</html>
chat.php — Messagerie par salon
<?php
require_once 'JsonObject.php';
require_once 'message.php';
require_once 'MessageDb.php';
require_once 'salons.php';
require_once 'SalonDb.php';

$salonId = $_GET['salonId'] ?? null;
if (!$salonId) { header("Location: salon_a.php"); exit; }

$salonDb = SalonDb::load();
$salon = $salonDb->getById((int)$salonId);
if (!$salon) die("Salon introuvable.");

$messageDb = MessageDb::load();
$messages = $messageDb->getBy("salonId", (int)$salonId);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $author  = $_POST['author']  ?? 'Anonyme';
    $content = trim($_POST['content'] ?? '');
    if (!empty($content)) {
        $msg = Message::create((int)$salonId, $author, $content);
        $messageDb->insert($msg);
        $messageDb->save();
        header("Location: chat.php?salonId=" . $salonId);
        exit;
    }
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Chat - <?= htmlspecialchars($salon->name) ?></title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-[#0a0b14] text-gray-200">
    <div class="max-w-3xl mx-auto mt-10">
        <h1 class="text-3xl font-bold text-cyan-400 mb-6">
            💬 <?= htmlspecialchars($salon->name) ?>
        </h1>
        <div class="bg-black/40 border border-gray-700 rounded-lg p-6 h-96 overflow-y-auto mb-6">
            <?php foreach ($messages as $msg): ?>
            <div class="mb-4">
                <p class="text-cyan-300 font-semibold">
                    <?= htmlspecialchars($msg->author) ?>
                    <span class="text-gray-500 text-xs">(<?= $msg->timestamp ?>)</span>
                </p>
                <p><?= htmlspecialchars($msg->content) ?></p>
            </div>
            <?php endforeach; ?>
        </div>
        <form method="POST" class="flex gap-3">
            <input name="author" placeholder="Votre pseudo" class="bg-gray-800 rounded px-3 py-2">
            <input name="content" placeholder="Message..." class="flex-1 bg-gray-800 rounded px-3 py-2">
            <button type="submit" class="bg-cyan-500 px-4 py-2 rounded font-bold">Envoyer</button>
        </form>
    </div>
</body>
</html>
JsonDb.php — Classe de stockage JSON générique
<?php
abstract class JsonDb {
    protected array $items = [];
    protected static string $file;

    public static function load(): static {
        $instance = new static();
        if (file_exists(static::$file)) {
            $data = json_decode(file_get_contents(static::$file), true);
            $instance->items = array_map(
                fn($d) => static::fromArray($d), $data ?? []
            );
        }
        return $instance;
    }

    public function save(): void {
        file_put_contents(
            static::$file,
            json_encode(array_map(fn($i) => $i->toArray(), $this->items), JSON_PRETTY_PRINT)
        );
    }

    public function insert(object $item): void {
        $this->items[] = $item;
    }

    public function get(): array {
        return $this->items;
    }

    public function getById(int $id): ?object {
        foreach ($this->items as $item) {
            if ($item->id === $id) return $item;
        }
        return null;
    }

    public function getBy(string $key, mixed $value): array {
        return array_filter($this->items, fn($i) => $i->$key === $value);
    }

    abstract protected static function fromArray(array $data): object;
}
?>
login.php — Authentification
<?php
session_start();
require_once 'Userdb.php';
require_once 'User.php';

$userDb = UserDb::load();
$users  = $userDb->get();

if (!empty($_POST)) {
    $email    = trim($_POST['email']);
    $password = $_POST['password'];

    foreach ($users as $u) {
        if ($u->email === $email && password_verify($password, $u->password)) {
            $_SESSION['user'] = $u;
            header("Location: salon_a.php");
            exit;
        }
    }
    $error = "Email ou mot de passe incorrect.";
}
?>
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="UTF-8"><title>Connexion</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 min-h-screen flex items-center justify-center">
    <div class="max-w-md w-full bg-white rounded-xl shadow-lg p-8">
        <h1 class="text-3xl font-bold text-gray-800 text-center mb-6">Connexion</h1>
        <?php if (isset($error)) echo "<p class='text-red-500 mb-4'>$error</p>"; ?>
        <form method="POST" class="space-y-4">
            <input type="email" name="email" placeholder="nom@exemple.com" required
                class="w-full px-4 py-3 rounded-lg border border-gray-300 outline-none">
            <input type="password" name="password" placeholder="Mot de passe" required
                class="w-full px-4 py-3 rounded-lg border border-gray-300 outline-none">
            <button type="submit" class="w-full bg-blue-600 text-white py-3 rounded-lg font-semibold">
                Se connecter
            </button>
        </form>
    </div>
</body>
</html>