PHP Comment faire Un Forum de base( french)

some help & tips

PHP Comment faire Un Forum de base( french)

Postby RAD on Fri Sep 01, 2006 2:37 am

PHP Comment faire Un Forum

Avant de commencer quoi que ce soit, il faut savoir que réaliser un beau forum n'est pas une opération vraiment simple.
En revanche, avec un peu de travail et surtout beaucoup de réflexion, on peut arriver à faire quelque chose de sympathique en assez peu de temps.

En effet, réfléchissons deux minutes à la question suivante :

De combien de pages WEB (et quelles sont leurs fonctions) avons-nous besoin pour réaliser un forum ?

Apres une rapide réflexion, on peut dire que l'on aura besoin de :
- une page d'accueil où l'on verra tous les sujets du forum (index.php)
- une page de lecture où l'on pourra lire les différents messages composant un sujet (lire_sujet.php)
- une page contenant un formulaire pour insérer un nouveau sujet (insert_sujet.php)
- une page contenant un formulaire pour insérer une réponse à un sujet (insert_reponse.php)

Ce qui nous fait un total de 4 pages à écrire.

Autre question :

Combien de tables SQL avons-nous besoin pour réaliser notre forum ?

On peut également dire que l'on aura besoin de 2 tables :
- une table contenant les sujets (que l'on nommera forum_sujets)
- une table comprenant les réponses à ces différents sujets (que l'on nommera forum_reponses)

Demandons-nous maintenant quels sont les attributs qui composent nos tables.

La table forum_sujet comportera :
- un attribut id (de type INT avec une option AUTO_INCREMENT) qui représentera la clé primaire de notre table, ce qui nous permettra de distinguer tous les sujets de notre forum (chaque sujet aura un id différent).
- un attribut auteur de type VARCHAR qui comportera le nom de la personne qui a posté ce sujet.
- un attribut titre de type text qui correspondra au titre du sujet.
- un attribut date_derniere_reponse de type datetime qui nous permettra de connaître la date de la dernière réponse de ce sujet (et ce pour mettre ce sujet en tête dans l'affichage).
En effet, dans la majorité des forums, lorsque l'on répond à un sujet, celui-ci se place ensuite toujours automatiquement en tête lorsque l'on affiche le forum.

Voici alors la structure de la table forum_sujets :


Code: Select all
CREATE TABLE forum_sujets (
    id int(6) NOT NULL auto_increment,
    auteur VARCHAR(30) NOT NULL,
    titre text NOT NULL,
    date_derniere_reponse datetime NOT NULL default '0000-00-00 00:00:00',
    PRIMARY KEY  (id)
) TYPE=MyISAM;



La table forum_reponses comportera elle :
- un attribut id (de type INT avec une option AUTO_INCREMENT) qui représentera la clé primaire de notre table, ce qui nous permettra de distinguer toutes les réponses à chaque sujet de notre forum (chaque réponse aura un id différent).
- un attribut auteur de type VARCHAR comportant le nom de la personne qui a posté cette réponse.
- un attribut message de type text qui correspond au message (réponse) que l'on postera.
- un attribut date_reponse de type datetime qui correspond à la date de postage de cette réponse.
- un attribut correspondance_sujet de type INT qui nous permettra de faire la liaison entre les réponses et les sujets du forum (cet attribut nous servira de jointure afin de connaître le sujet auquel appartient telle ou telle réponse).

Voici la structure de la table :


Code: Select all
CREATE TABLE forum_reponses (
    id int(6) NOT NULL auto_increment,
    auteur VARCHAR(30) NOT NULL,
    message text NOT NULL,
    date_reponse datetime NOT NULL default '0000-00-00 00:00:00',
    correspondance_sujet int(6) NOT NULL,
    PRIMARY KEY  (id)
) TYPE=MyISAM;



Voila déjà une bonne chose de faite.
Reste ensuite à écrire les différentes pages.

Voyons tout d'abord la page index.php.
Apres une rapide réflexion, on peut se rendre compte que sur cette page, nous aurons besoin de :
- un lien permettant d'insérer un nouveau sujet.
- le nom de l'auteur du sujet.
- le titre su sujet.
- la date de la dernière réponse à ce sujet.
- mais aussi l'id de ce sujet (afin de faire la jointure entre les deux tables).

Sur cette page, on veut également qu'un lien soit présent au niveau de chaque titre de sujet afin de lire les différentes réponses appartenant à chaque sujet (c'est là que l'on aura besoin de l'id).

On aura alors (page index.php):


Code: Select all
<html>
<head>
<title>Index de notre forum</title>
</head>
<body>

<!-- on place un lien permettant d'accéder à la page contenant le formulaire d'insertion d'un nouveau sujet -->
<a href="./insert_sujet.php">Insérer un sujet</a>

<br /><br />

<?php
// on se connecte à notre base de données
$base = mysql_connect ('serveur', 'login', 'password');
mysql_select_db ('nom_base', $base) ;

// préparation de la requete
$sql = 'SELECT id, auteur, titre, date_derniere_reponse FROM forum_sujets ORDER BY date_derniere_reponse DESC';

// on lance la requête (mysql_query) et on impose un message d'erreur si la requête ne se passe pas bien (or die)
$req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

// on compte le nombre de sujets du forum
$nb_sujets = mysql_num_rows ($req);

if ($nb_sujets == 0) {
    echo 'Aucun sujet';
}
else {
    ?>
    <table width="500" border="1"><tr>
    <td>
    Auteur
    </td><td>
    Titre du sujet
    </td><td>
    Date dernière réponse
    </td></tr>
    <?php
    // on va scanner tous les tuples un par un
    while ($data = mysql_fetch_array($req)) {

    // on decompose la date
    sscanf($data['date_derniere_reponse'], "%4s-%2s-%2s %2s:%2s:%2s", $annee, $mois, $jour, $heure, $minute, $seconde);

    // on affiche les résultats
    echo '<tr>';
    echo '<td>';

    // on affiche le nom de l'auteur de sujet
    echo stripslashes(htmlentities(trim($data['auteur'])));
    echo '</td><td>';

    // on affiche le titre du sujet, et sur ce sujet, on insère le lien qui nous permettra de lire les différentes réponses de ce sujet
    echo '<a href="./lire_sujet.php?id_sujet_a_lire=' , $data['id'] , '">' , stripslashes(htmlentities(trim($data['titre']))) , '</a>';

    echo '</td><td>';

    // on affiche la date de la dernière réponse de ce sujet
    echo $jour , '-' , $mois , '-' , $annee , ' ' , $heure , ':' , $minute;
    }
    ?>
    </td></tr></table>
    <?php
}

// on libère l'espace mémoire alloué pour cette requête
mysql_free_result ($req);
// on ferme la connection à la base de données.
mysql_close ();
?>
</body>
</html>



Si vous n'êtes pas déjà mort, on va s'intéresser maintenant à la page lire_sujet.php permettant de lire tous les messages d'un sujet.

D'après le code de la page index.php, on remarque déjà que grâce au lien mis sur le titre de chaque sujet, on aura une variable $_GET['id_sujet_a_lire'] dans la page lire_sujet.php qui correspondra à l'id du sujet dont nous souhaitons lire tous les messages.

Cette explication faite, la page lire_sujet.php ne pose aucun problème puisqu'il s'agit tout simplement de sélectionner les réponses d'un certain sujet et de les afficher (de quel sujet ? et bien tout simplement celui dont l'id est égal à $_GET['id_sujet_a_lire']).

Egalement, n'oublions pas de fournir un lien vers la page insert_reponse.php nous permettant de poster des réponses pour le sujet que nous sommes en train de lire.

On aura alors le code suivant (page lire_sujet.php) :


Code: Select all
<html>
<head>
<title>Lecture d'un sujet</title>
</head>
<body>

<?php
if (!isset($_GET['id_sujet_a_lire'])) {
    echo 'Sujet non défini.';
}
else {
?>
    <table width="500" border="1"><tr>
    <td>
    Auteur
    </td><td>
    Messages
    </td></tr>
    <?php
    // on se connecte à notre base de données
    $base = mysql_connect ('serveur', 'login', 'password');
    mysql_select_db ('nom_base', $base) ;
   
    // on prépare notre requête
    $sql = 'SELECT auteur, message, date_reponse FROM forum_reponses WHERE correspondance_sujet="'.$_GET['id_sujet_a_lire'].'" ORDER BY date_reponse ASC';

    // on lance la requête (mysql_query) et on impose un message d'erreur si la requête ne se passe pas bien (or die)
    $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

    // on va scanner tous les tuples un par un
    while ($data = mysql_fetch_array($req)) {

        // on décompose la date
        sscanf($data['date_reponse'], "%4s-%2s-%2s %2s:%2s:%2s", $annee, $mois, $jour, $heure, $minute, $seconde);

        // on affiche les résultats
        echo '<tr>';
        echo '<td>';

        // on affiche le nom de l'auteur de sujet ainsi que la date de la réponse
        echo stripslashes(htmlentities(trim($data['auteur'])));
        echo '<br />';
        echo $jour , '-' , $mois , '-' , $annee , ' ' , $heure , ':' , $minute;

        echo '</td><td>';

        // on affiche le message
        echo nl2br(stripslashes(htmlentities(trim($data['message']))));
        echo '</td></tr>';
    }

    // on libère l'espace mémoire alloué pour cette reqête
    mysql_free_result ($req);
    // on ferme la connection à la base de données.
    mysql_close ();
    ?>

    <!-- on ferme notre table html -->
    </table>
    <br /><br />
    <!-- on insère un lien qui nous permettra de rajouter des réponses à ce sujet -->
    <a href="./insert_reponse.php?numero_du_sujet=<?php echo $_GET['id_sujet_a_lire']; ?>">Répondre</a>
    <?php
}
?>
<br /><br />
<!-- on insère un lien qui nous permettra de retourner à l'accueil du forum -->
<a href="./index.php">Retour à l'accueil</a>

</body>
</html>


Et voila :)

Notre forum est à présent terminé en ce qui concerne l'affichage des titres des sujets et des différentes réponses.

Reste maintenant à faire les 4 dernières pages, celles qui vous nous permettre d'insérer des nouveaux sujets ainsi que des nouvelles réponses.

Prenons tout d'abord la page insert_sujet.php.
Cette page propose tout simplement un formulaire nous permettant de saisir notre nom (le nom de l'auteur du sujet), un titre de sujet ainsi qu'un message (soit en fait, le premier message de notre sujet).

On aura alors le code suivant (page insert_sujet.php)
Code: Select all
<?php
// on teste si le formulaire a été soumis
if (isset ($_POST['go']) && $_POST['go']=='Poster') {
    // on teste la déclaration de nos variables
    if (!isset($_POST['auteur']) || !isset($_POST['titre']) || !isset($_POST['message'])) {
        $erreur = 'Les variables nécessaires au script ne sont pas définies.';
    }
    else {
        // on teste si les variables ne sont pas vides
        if (empty($_POST['auteur']) || empty($_POST['titre']) || empty($_POST['message'])) {
            $erreur = 'Au moins un des champs est vide.';
        }

        // si tout est bon, on peut commencer l'insertion dans la base
        else {
            // on se connecte à notre base
            $base = mysql_connect ('serveur', 'login', 'password');
            mysql_select_db ('nom_base', $base) ;
           
            // on calcule la date actuelle
            $date = date("Y-m-d H:i:s");

            // préparation de la requête d'insertion (pour la table forum_sujets)
            $sql = 'INSERT INTO forum_sujets VALUES("", "'.addslashes($_POST['auteur']).'", "'.addslashes($_POST['titre']).'", "'.$date.'")';

            // on lance la requête (mysql_query) et on impose un message d'erreur si la requête ne se passe pas bien (or die)
            mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error());

            // on recupère l'id qui vient de s'insérer dans la table forum_sujets
            $id_sujet = mysql_insert_id();

            // lancement de la requête d'insertion (pour la table forum_reponses
            $sql = 'INSERT INTO forum_reponses VALUES("", "'.addslashes($_POST['auteur']).'", "'.addslashes($_POST['message']).'", "'.$date.'", "'.$id_sujet.'")';

            // on lance la requête (mysql_query) et on impose un message d'erreur si la requête ne se passe pas bien (or die)
            mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error());

            // on ferme la connexion à la base de données
            mysql_close();

            // on redirige vers la page d'accueil
            header('Location: index.php');

            // on termine le script courant
            exit;
        }
    }
}
?>
<html>
<head>
<title>Insertion d'un nouveau sujet</title>
</head>

<body>

<!-- on fait pointer le formulaire vers la page traitant les données -->
<form action="insert_sujet.php" method="post">
<table>
<tr><td>
<span class="gras">Auteur :</span>
</td><td>
<input type="text" name="auteur" maxlength="30" size="50" value="<?php if (isset($_POST['auteur'])) echo stripslashes(htmlentities(trim($_POST['auteur']))); ?>">
</td></tr><tr><td>
<span class="gras">Titre :</span>
</td><td>
<input type="text" name="titre" maxlength="50" size="50" value="<?php if (isset($_POST['titre'])) echo stripslashes(htmlentities(trim($_POST['titre']))); ?>">
</td></tr><tr><td>
<span class="gras">Message :</span>
</td><td>
<textarea name="message" cols="50" rows="10"><?php if (isset($_POST['message'])) echo stripslashes(htmlentities(trim($_POST['message']))); ?></textarea>
</td></tr><tr><td><td align="right">
<input type="submit" name="go" value="Poster">   
</td></tr></table>
</form>
<?php
// on affiche les erreurs éventuelles
if (isset($erreur)) echo '<br /><br />',$erreur;
?>
</body>
</html>

A présent, le système permettant d'insérer un nouveau sujet, est terminé. Il ne nous reste plus qu'à réaliser 1 page : celle contenant le formulaire pour insérer une réponse à un sujet (la page insert_reponse.php).

D'après la page lire_sujet.php, on remarque que le lien présent dans cette page (lien permettant d'accéder au formulaire de réponses) comporte une variable numero_du_sujet qui prend la valeur de l'id du sujet dont on veut répondre.
Par conséquent, on va transporter cette variable dans notre page insert_reponse.php.

On aura alors le code suivant (page insert_reponse.php) :


Code: Select all
<?php
// on teste si le formulaire a été soumis
if (isset ($_POST['go']) && $_POST['go']=='Poster') {
    // on teste le contenu de la variable $auteur
    if (!isset($_POST['auteur']) || !isset($_POST['message']) || !isset($_GET['numero_du_sujet'])) {
        $erreur = 'Les variables nécessaires au script ne sont pas définies.';
    }
    else {
        if (empty($_POST['auteur']) || empty($_POST['message']) || empty($_GET['numero_du_sujet'])) {
            $erreur = 'Au moins un des champs est vide.';
        }
        // si tout est bon, on peut commencer l'insertion dans la base
        else {
            // on se connecte à notre base de données
            $base = mysql_connect ('serveur', 'login', 'password');
            mysql_select_db ('nom_base', $base) ;

            // on recupere la date de l'instant présent
            $date = date("Y-m-d H:i:s");

            // préparation de la requête d'insertion (table forum_reponses)
            $sql = 'INSERT INTO forum_reponses VALUES("", "'.addslashes($_POST['auteur']).'", "'.addslashes($_POST['message']).'", "'.$date.'", "'.$_GET['numero_du_sujet'].'")';

            // on lance la requête (mysql_query) et on impose un message d'erreur si la requête ne se passe pas bien (or die)
            mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error());

            // préparation de la requête de modification de la date de la dernière réponse postée (dans la table forum_sujets)
            $sql = 'UPDATE forum_sujets SET date_derniere_reponse="'.$date.'" WHERE id="'.$_GET['numero_du_sujet'].'"';

            // on lance la requête (mysql_query) et on impose un message d'erreur si la requête ne se passe pas bien (or die)
            mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error());

            // on ferme la connexion à la base de données
            mysql_close();

            // on redirige vers la page de lecture du sujet en cours
            header('Location: lire_sujet.php?id_sujet_a_lire='.$_GET['numero_du_sujet']);

            // on termine le script courant
            exit;
        }
    }
}
?>

<html>
<head>
<title>Insertion d'une nouvelle réponse</title>
</head>

<body>

<!-- on fait pointer le formulaire vers la page traitant les données -->
<form action="insert_reponse.php?numero_du_sujet=<?php echo $_GET['numero_du_sujet']; ?>" method="post">
<table>
<tr><td>
<span class="gras">Auteur :</span>
</td><td>
<input type="text" name="auteur" maxlength="30" size="50" value="<?php if (isset($_POST['auteur'])) echo stripslashes(htmlentities(trim($_POST['auteur']))); ?>">
</td></tr><tr><td>
<span class="gras">Message :</span>
</td><td>
<textarea name="message" cols="50" rows="10"><?php if (isset($_POST['message'])) echo stripslashes(htmlentities(trim($_POST['message']))); ?></textarea>
</td></tr><tr><td><td align="right">
<input type="submit" name="go" value="Poster">   
</td></tr></table>
</form>
<?php
if (isset($erreur)) echo '<br /><br />',$erreur;
?>
</body>
</html>


Et voila, notre forum est à présent terminé :)


Que faire en plus ?

En effet, ce forum, si vous l'avez testé, n'a pas vraiment une gueule super fun, malgré le fait qu'il fonctionne parfaitement.
Pour l'améliorer, vous pouvez par exemple améliorer grandement sa présentation en utilisant de belles feuilles de style (css).
Vous pouvez également tester le contenu des variables (voir si elles sont vides ou pas avec la fonction empty et ainsi éviter que des messages vides viennent pollués votre forum).
Ou bien, pourquoi ne pas tenter de faire une petite gestion de simleys ?

A vos claviers :)


♠ - ω Comment is CLOSED for This POST ω - ♠
RAD

Image La plus grande erreur que puisse faire un homme est d'avoir peur d'en faire une.
User avatar
RAD
Administrateur - Site Admin
 
Posts: 532
Joined: Thu Aug 31, 2006 12:02 am

Return to WEBMASTER

Who is online

Users browsing this forum: No registered users and 1 guest

cron