Programmation PHP/Exemples/MiniForum

Faire un mini forum de discussion

modifier

Bon nombre de forums sur internet ont repris des opensources et les ont customisé. Dans cet article, nous verrons comment simplement opposer de meilleures solutions, plus souples et personnelles. Ce chapitre traitera du programme à fournir pour cette solution sans proposer de sécurisation.

Introduction

modifier

Voici un forum modulaire, universel, illimité, fonctionnel et très réactif mais à sécuriser avec MySQL en backend et HTML en frontend.

Architecture

modifier

À bâtir en MVC, le forum est segmenté comme :

./index.php
./config.inc.php

// STATICAL MODULES

./Objects/
./Objects/frameset.inc.php // main frameset
./Objects/mainPage.inc.php // main pages content

// FUNCTIONNAL MODULES

./Libraries/

Déploiement

modifier

La méthodologie processus unifié fonctionne par itérations successives et augmentation, amélioration du code. On obtient donc pour chaque module différentes itérations représentatives de l'état d'avancement de l'application. L'état 0 ou incrément 0 étant l'ébauche et incrément 1, la première itération de l'applicatif.

 Fichier : config.inc.php
<?php
/*  */

define('OBJ', './Objects/');
define('LIB', './Libraries/');

$cnx = array('host'=>'localhost','user'=>'root','db'=>'miniForum','pass'=>'');

?>

increment 0 : index.php

 Fichier : index.php
<?php
/* Mini Forum - main entry 
	
	This is a mini forum 
	
	version : 	1.0
	date : 		2009 07 28
	author : 	zulul
	
*/

require_once "./config.inc.php";
require_once OBJ . "frameset.inc.php";

echo $_mainSet;

?>

increment 1 : index.php

 Fichier : index.php
<?php
/* Mini Forum - main entry 
	
	This is a mini forum 
	
	version : 	1.0
	date : 		2009 07 28
	author : 	zulul
	
*/

@session_start();

require_once "./config.inc.php";
require_once OBJ . "frameset.inc.php";

// lib
require_once LIB . "Connectivity.cla.php";
require_once LIB . "Request.cla.php";
require_once LIB . "utils.fnc.php";

// autho
if(chk_usr($cnx))
	$_SESSION['autho'] = 1;
	
echo $_mainSet;

?>


increment 2 : index.php

 Fichier : index.php
<?php
/* Mini Forum - main entry 
	
	This is a mini forum 
	
	version : 	1.0
	date : 		2009 07 28
	author : 	zulul
	
*/

@session_start();

require_once "./config.inc.php";

// lib
require_once LIB . "Connectivity.cla.php";
require_once LIB . "Request.cla.php";
require_once LIB . "utils.fnc.php";

// page listener
require_once OBJ . "listener.inc.php";

// autho
if(chk_usr($cnx))
{
	$_SESSION['autho'] = 1;
}

// controling application
require_once OBJ . "controler.inc.php";
// variing frameset call
require_once OBJ . "frameset.inc.php";


# OUTPUT
echo $_mainSet;

?>

Objects

modifier
 Fichier : frameset.inc.php
 
<?php
/* main page 

*/

require_once OBJ."mainPage.inc.php";

$_mainSet = <<<EOPAGE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//FR" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html lang="fr" xml:lang="fr">
 <head>
	{$_content['title']}
	{$_content['meta']}
	{$_content['style']}
 </head>
 <body>
	{$_content['main']}
 </body>
</html>
EOPAGE;
?>

increment 3 : frameset.inc.php

 Fichier : frameset.inc.php
 
 <head>
	{$_content['title']}
	{$_content['meta']}
	{$_content['script']}
	{$_content['style']}
 </head>

increment 0 : mainPage.inc.php

 Fichier : mainPage.inc.php
 
<?php
/* Main page content 

*/

$title 		= ':: TITLE ::';
$meta		= '';
$style		= '';


// head content
$_content['title']	= '<title>'.$title.'</title>';
$_content['meta']	= '<meta>'.$meta.'</meta>';
$_content['style']	= '<style>

	body
	{
		margin:0 0 0 0;
		font-family:tahoma;
		font-size:10px;
	}
	
	table td
	{
		border:1px solid;
		padding:5px;
		margin:5px;
	}

	.grey
	{
		background-color:#eee;
	}
	
	.creeper
	{
		border:1px solid;
		height:200px;
	}
	
</style>';

// content contents
$_content['authorize'] = '
	<div id="cAuthorize">
		
		<table align="center" width="100%">
			<tr><td class="grey">pseudo <input type="text" value=""/></td></tr>
			<tr><td class="grey">passwd <input type="text" value=""/></td></tr>
			<tr><td class="grey"><input type="button" value="submit()"/></td></tr>
		</table>
	</div>
	
';

// content contents
$_content['skyCreeper'] = '
	<div>
		<div class="creeper">
		<br/>this is the content
		<br/>this is thec content
		<br/>this is the content	
		</div>
	</div>';

$_content['pager'] = <<<EOPAGE
	<div id="cAuthorize">
		
		<table width="100%">
			<tr valign="top"><td width="50%" height="250" class="grey">:: 1 ::</td><td class="grey">:: 2 ::</td></tr>
			<tr valign="top"><td width="50%" height="250" class="grey">:: 3 ::</td><td class="grey">:: 4 ::</td></tr>
		</table>
		
	</div>
EOPAGE;

// body contents
$_content['main']	= <<<EOPAGE
	<table width="99%" height="600">
		
		<!-- its still better to stay with table instead of divs -->
		<tr>
			<td height="18" colspan="2" width="99%" align="center" class="grey">
				:: THIS IS TOP CONTENT ::			
			</td>
		</tr>
		<tr valign="top">
			<td width="20%">
				{$_content['authorize']}
				{$_content['skyCreeper']}
			</td>
			<td width="79%">
				{$_content['pager']}
			</td>
		</tr>
		<tr>
			<td height="18" colspan="2" width="99%" align="center" class="grey">:: THIS IS BOTTOM CONTENT ::</td>
		</tr>
	</table>
EOPAGE;

?>

increment 1 : listener.inc.php

 Fichier : listener.inc.php
 
<?php
/* application listener

*/

/* flag cases

*/
switch(true)
{
	case(@$_REQUEST['aut']=='0'):
		//action disconnect
		unset($_SESSION['autho'],$_SESSION['userMod']);
		break;
	
	/*
	case ():
		break;
	*/
}

?>


increment 1 : controler.inc.php

 Fichier : controler.inc.php
 
<?php
/* application controler

*/

# INIT

/* admin and mod status control 

*/
if(@$_REQUEST['aut']!='0')
{
	// moderating user
	mod();
}

# PREPARE

/* cases

*/
if(@$_SESSION['userMod'])
{//
	
	if(preg_match('/[0]/',$_SESSION['userMod']['adm']))
		$_mod[0] = 'superAdmin';
		
	if(preg_match('/[1]/',$_SESSION['userMod']['adm']))
		$_mod[0] = 'Admin';
		
	if(preg_match('/[0]/',$_SESSION['userMod']['mod']))
		$_mod[1] = 'superModerator';
		
	if(preg_match('/[1]/',$_SESSION['userMod']['mod']))
		$_mod[1] = 'Moderator';
}
?>

increment 1 : mainPage.inc.php

À cette itération, l'authentification du user est fonctionnelle.
Le snippet content['authorize'] change de mode.
 Fichier : mainPage.inc.php
... 
// content contents
$_content['authorize'] = (!@$_SESSION['autho'])?'
	<div id="cAuthorize">
		<form action="" method="post" name="form">
		<table align="center" width="100%">
			<tr><td colspan="2" class="grey">pseudo <input name="login" type="text" value=""/></td></tr>
			<tr><td colspan="2" class="grey">passwd <input name="pass" type="text" value=""/></td></tr>
			<tr><td class="grey" align="left"><input type="submit" value="submit" /> </td>
			<td align="right"><a href="">forgot password</a><br/><a href="">new registration</a></td></tr>
		</table>
		</form>
	</div>
':'logged';
...

increment 2 : mainPage.inc.php

À cette itération, l'attribution des privilèges du user est fonctionnelle.
Le snippet content['authorize'] affiche le statut user mode.
 Fichier : mainPage.inc.php
 
// content contents
$_content['authorize'] = (!@$_SESSION['autho'])?'
	<div id="cAuthorize">
		<form action="'.$_SERVER['PHP_SELF'].'" method="post" name="form">
		<table align="center" width="100%">
			<tr><td colspan="2" class="grey">pseudo <input name="login" type="text" value=""/></td></tr>
			<tr><td colspan="2" class="grey">passwd <input name="pass" type="text" value=""/></td></tr>
			<tr><td class="grey" align="left"><input type="submit" value="submit" /> </td>
			<td align="right"><a href="">forgot password</a><br/><a href="">new registration</a></td></tr>
		</table>
		</form>
	</div>
':'<div id="cAuthorize"><table align="center" width="100%"><tr><td>logged | 
	<a href="'.$_SERVER['PHP_SELF'].'?aut=0">disconnect</a><br/><br/>Status : '.@$_mod[0] . " " . @$_mod[1] .'</td></tr></table></div>';

// content contents
$_content['containers'] = '
	<table width="100%"><tr><td>:: PARTNER 1 ::</td></tr></table>
	<table width="100%"><tr><td>:: PARTNER 2 ::</td></tr></table>
';

increment 3 : jsScript.inc.php

intégration des javascripts
 Fichier : mainPage.inc.php
<?php

	$script = '
		/* javascript scripts
		
		*/
		
		function showHide(obj)
		{//	>(element)
			
			if(obj.style.display!="none")
				obj.style.display="none";
			else
				obj.style.display="";
		}
	
	';

?>

increment 3 : pages.inc.php

contenus des pages
 Fichier : pages.inc.php
<?php
/* pager contents

*/

// mod 1
if(@$_REQUEST['mod'] == '1' && @$_SESSION['autho']) //
{
	
	// list rubriq
	$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
	foreach($_res as $_tmp)
	{
		@$str .= '<br/><form method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1" name="f3"><input name="iDel" type="hidden" value="' . $_tmp['id'] . '" /><input type="submit" value="[-]"/> <a href="">' . $_tmp['title'] . '</a></form>';
	}
	
	$_content['pager']  = '
	<div class="title">Rubriques existantes | <span class="toAct" onclick="showHide(getElementById(\'cRubriq\'));">Ajouter une rubrique</span><br/>
		<!-- Rubriq adder -->
		<table width="100%">
			<tr valign="top">
				<td>
					<div id="cRubriq">Ajouter une nouvelle rubrique
						<form name="f2" method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1">
							<p><input name="iRubriq" type="text" size="50" /><input type="submit" value="add"/></p>
						</form>
					</div>
				</td>
			</tr>
			<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
		</table>
	</div>
	';
	
}

// rub 1
if(@$_REQUEST['rub'] == '1') //
{
	
	if(!@$_REQUEST['tId'])
	{
		// list rubriq
		$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
		foreach($_res as $_tmp)
		{
			@$str .= '<br/> <a href="'.$_SERVER['PHP_SELF'].'?rub=1&tId=' . $_tmp['id'] . '">' . $_tmp['title'] . '</a>';
		}
		
		$_content['pager']  = '
		<div class="title">Rubriques existantes
			<table width="100%">
				<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
			</table>
		</div>
		';
		
	} else {
		
		// list rubriq
		$_res=Request::SQL($cnx,'SELECT * FROM contents WHERE topicsId=' . @$_REQUEST['tId'] . ' ORDER BY id');
		foreach($_res as $_tmp)
		{
			@$str .= '<br/> <a href="' . $_SERVER['PHP_SELF'] . '?rub=1&tId=' . $_tmp['topicsId'] . '">' . $_tmp['subject'] . '</a>';
		}
		
		$_content['pager']  = '
		<div class="title">Topics existants
			<table width="100%">
			<!-- Topics adder -->
				<tr valign="top">
					<td>
						<div id="cTopics">Ajouter un nouveau sujet
							<form name="f4" method="post" action="' . $_SERVER['PHP_SELF'] . '?rub=1">
								<p><input name="iTopics" type="text" size="50" /><input type="submit" value="add" /></p>
							</form>
						</div>
					</td>
				</tr>
				<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
			</table>
		</div>
		';
		
	}
}
?>


increment 4 : pages.inc.php

contenus des pages complétés
 Fichier : pages.inc.php
<?php
/* pager contents

*/

// mod 1
if(@$_REQUEST['mod'] == '1' && @$_SESSION['autho']) //
{
	
	// list rubriq
	$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
	foreach($_res as $_tmp)
	{
		@$str .= '<br/><form method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1" name="f3"><input name="iDel" type="hidden" value="' . $_tmp['id'] . '" /><input type="submit" value="[-]"/> <a href="">' . $_tmp['title'] . '</a></form>';
	}
	
	$_content['pager']  = '
	<div class="title">Rubriques existantes | <span class="toAct" onclick="showHide(getElementById(\'cRubriq\'));">Ajouter une rubrique</span><br/>
		<!-- Rubriq adder -->
		<table width="100%">
			<tr valign="top">
				<td>
					<div id="cRubriq">Ajouter une nouvelle rubrique
						<form name="f2" method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1">
							<p><input name="iRubriq" type="text" size="50" /><input type="submit" value="add"/></p>
						</form>
					</div>
				</td>
			</tr>
			<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
		</table>
	</div>
	';
	
}

// rub 1
if(@$_REQUEST['rub'] == '1') //
{
	if(!@$_REQUEST['tId'])
	{
		// list rubriq
		$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
		foreach($_res as $_tmp)
		{
			@$str .= '<br/> <a href="'.$_SERVER['PHP_SELF'].'?rub=1&tId=' . $_tmp['id'] . '">' . $_tmp['title'] . '</a>';
		}
		
		$_content['pager']  = '
		<div class="title">Rubriques existantes
			<table width="100%">
				<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
			</table>
		</div>
		';
		
	} else {
		
		// list rubriq
		$_res=Request::SQL($cnx,'SELECT * FROM contents WHERE topicsId="' . @$_REQUEST['tId'] . '" ORDER by id');
		foreach($_res as $_tmp)
		{
			@$str .= '<br/> <a href="' . $_SERVER['PHP_SELF'] . '?aId='.$_tmp['id'].'&art=1&tId=' . $_tmp['topicsId'] . '">' . $_tmp['subject'] . '</a>';
		}
		
		$_content['pager']  = '
		<div class="title">Topics existants
			<table width="100%">
			<!-- Topics adder -->
				<tr valign="top">
					<td>
						<div id="cTopics">Ajouter un nouveau sujet
							<form name="f4" method="post" action="' . $_SERVER['PHP_SELF'] . '?rub=1">
								<p>
								<input name="tId" type="hidden" value="'.$_REQUEST['tId'].'" />
								<input name="iTopics" type="text" size="50" /><input type="submit" value="add" /></p>
							</form>
						</div>
					</td>
				</tr>
				<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
			</table>
		</div>
		';
	}
}

if(@$_REQUEST['art']=='1' && @$_REQUEST['tId'])
{
		// list article
		$_res=Request::SQL($cnx,'SELECT * FROM contents WHERE topicsId= ' .@$_REQUEST['tId'] . ' ORDER BY id');
		foreach($_res as $_tmp)
		{
			@$str .= '<table width="100%">
				<tr><td width="10%" rowspan="2">:: IMAGE ::<br/>:: usrId ' . $_tmp['usrId'] . ' ::</td>
					<td width="90%"><a href="'.$_SERVER['PHP_SELF'].'?aId='.$_tmp['id'].'&art=1&tId=' . $_tmp['topicsId'] . '">' . $_tmp['subject'] . '</a></td>
				</tr>
				<tr><td width="90%">' . $_tmp['content'] . '</td></tr>
				';
		}
		
		$rec = getRecordNfo($cnx,'contents', @$_REQUEST['aId']);
		$_content['pager']  = @$str . '
		<div class="article">
			<table width="100%">
				<tr valign="top">
					<td>
						<div id="cArticle"><b>Introduisez votre commentaire : </b><br/><br/>
							<form name="f5" method="post" action="' . @$_SERVER['PHP_SELF'] . '?art=1&tId=' . @$_REQUEST['tId'] . '>
								<p>
									<input name="tId" type="hidden" value="' . @$_REQUEST['tId'] . '" />
									<input name="aId" type="hidden" value="' . @$_REQUEST['aId'] . '" />
									<input name="iSubject" type="text" value="' . (@$rec['subject']) . '" />
									<textarea name="iContent" rows="5" style="width:95%">' . (@$res['content']) . '</textarea>
									<input type="submit" value="add" />
								</p>
							</form>
						</div>
					</td>
				</tr>
			</table>
		</div>
		';
}

?>

increment 4 : controler.inc.php

controler complété
 Fichier : controler.inc.php
<?php
/* application controler

*/

# INIT

/* admin and mod status control 

*/
if(@$_REQUEST['aut']!='0')
{
	// moderating user
	mod();
}

# PREPARE

/* cases

*/
if(@$_SESSION['userMod'])
{//
	
	if(preg_match('/[0]/',$_SESSION['userMod']['adm']))
		$_mod[0] = 'superAdmin';
		
	if(preg_match('/[1]/',$_SESSION['userMod']['adm']))
		$_mod[0] = 'Admin';
		
	if(preg_match('/[0]/',$_SESSION['userMod']['mod']))
		$_mod[1] = 'superModerator';
		
	if(preg_match('/[1]/',$_SESSION['userMod']['mod']))
		$_mod[1] = 'Moderator';
}

if(@$_REQUEST['mod']=='1')
{// add rubriq
	
	if(@$_REQUEST['iRubriq'])
		Request::SQL($cnx,'INSERT INTO topics (title) values ("' . $_POST['iRubriq'] . '");');
	
	if(@$_REQUEST['iDel'])
	{
		Request::SQL($cnx,'DELETE FROM topics WHERE id='.$_REQUEST['iDel'].';');
	}
}

if(@$_REQUEST['rub']=='1' && @$_REQUEST['tId'])
{
	if(@$_REQUEST['iTopics'])
	{
		Request::SQL($cnx,'INSERT INTO contents (topicsId,subject,usrId) values (' . $_REQUEST['tId'] . ', "' . $_REQUEST['iTopics'] . '",' . $_SESSION['userId'] . ')');
	}
}

if(@$_REQUEST['art']=='1')
{
	if(@$_REQUEST['iContent'])
	{
		Request::SQL($cnx,'UPDATE contents SET content="' . $_REQUEST['iContent'] . '" WHERE id=' . $_REQUEST['aId']);
	}
}

?>
À ce stade on a une ébauche de layout pour notre forum :

   

Constatations

modifier

Après le login, on a :

[1] admin
[2] mod
[3] user

[2] & [3] sont similaires, quelques indicateurs à basculer dans la base. Il reste donc deux cas.

L'admin aura sa propre IHM avec fonctions élevées sur le forum.

RUP - Rational Unified Process (ou comment coder ?)

modifier

La granularité de la solution s'effectuera par l'affinage des modules.

Il n'est pas intelligent de coder en procédurale ou suivant un développement linéaire dans ce cas. Chaque module ou addon s'interfacera par adjonction de classes et snippets. Ceux-ci étant bien définis quand aux (in/out)put, avec le type précis.

De cette manière l'applicatif sera modulaire et évolutif.

Module administratif

modifier

Le forum doit être dédié aux légumes. L'admin doit avoir le choix de créer ces différents sujets principaux.

Par exemple les sections :

  • coups de cœur,
  • espace détente,
  • nouveauté & trouvailles,
  • légumes.

Bibliothèques

modifier

Nous aurons d'emblée besoin des deux utilitaires :

[classes]

Les classes usuelles
  • Connectivity
  • Request

[functions]

Les fonctionnalités usuelles


[classes]

 Fichier : Connectivity.cla.php
<?php
/* Connectivity class

	version : 	1.0
	author  :	zulul
	date	:	2009 07 28

*/

class Connectivity 
{//
  var $ident;
  var $sql = array('host'=>'','user'=>'','db'=>'','pass'=>'');

  //INIT
  function DB ($cnx) {
		$this->sql = $cnx;
		$this->connect();
  }
  
  function connect ()  {
     // Connect to MySQL

     $this->ident = mysql_connect($this->sql['host'], $this->sql['user'], $this->sql['pass']);
	 // Select assigned DB
     $this->sql['db']?mysql_select_db($this->sql['db']):0;
  }
	
  function disconnect () {
     // Close the connection
     if (!mysql_close($this->ident)) {
       die("Could not close Database");
     }
  }
}
?>


 Fichier : Request.cla.php
<?php
/* Request class

*/

class Request 
{//
	
	var $res, $Connectivity;

	function SQL($cnx,$sql) {
		
		$DB=new Connectivity($cnx);
		$res = mysql_fetch_all(mysql_query($sql,$DB->ident));
		$DB->disconnect();
	
	return($res);
	}
}
?>


[functions]

 Fichier : utils.fnc.php
<?php
/* utilities functions

*/

/* fetch all db results

*/
function mysql_fetch_all($query, $kind = 'assoc') 
{
   $result = array();
   $kind = $kind === 'assoc' ? $kind : 'row';
   eval('while(@$r = mysql_fetch_'.$kind.'($query)) array_push($result, $r);');
   return $result;
}

/* check if user is on db

*/
function chk_usr($cnx)
{
	if(!isset($_SESSION['autho']))
	{
		if(@$_REQUEST['login']&&@$_REQUEST['pass'])
		{
			return count(Request::SQL($cnx,'SELECT * FROM users WHERE login="'.$_POST['login'].'" and pass="'.$_POST['pass'].'"'))?true:false;
		}
	}else{
		return true;
	}
}

?>

increment 2 : utils.fnc.php

 Fichier : utils.fnc.php
/* dump array 2 html

*/
function print_r_html($data,$return_data=false)
{
    $data = print_r($data,true);
    $data = str_replace( " ","&nbsp;", $data);
    $data = str_replace( "\r\n","<br/>\r\n", $data);
    $data = str_replace( "\r","<br/>\r", $data);
    $data = str_replace( "\n","<br/>\n", $data);
 
    if (!$return_data)
        echo $data;
    else
        return $data;
}

/* adm and mod status checker

*/
function mod()
{
	if(@$_SESSION['userMod'])
	{
		foreach($_SESSION['userMod'] as $_tmp)
		{
			$_stat = explode("/",$_tmp);
			@$_SESSION['userMod'][$_stat[0]]=$_stat[1];
		}
	}
}


increment 4 : utils.fnc.php

add function
 Fichier : utils.inc.ohp
/* get record by id

*/
function getRecordNfo($cnx, $table, $id)
{
	return count($res=Request::SQL($cnx,"SELECT * FROM $table WHERE id=$id"))?$res[0]:false;
}

Modélisation

modifier

La modélisation est fonction du métier et des affinités. En voici une fonctionnelle pour notre exemple :

 Fichier : install.sql
-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
--
-- Serveur: localhost
-- Généré le : Mar 28 Juillet 2009 à 19:11
-- Version du serveur: 5.1.36
-- Version de PHP: 5.3.0

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Base de données: `miniForum`
--

-- --------------------------------------------------------

--
-- Structure de la table `contents`
--

CREATE TABLE IF NOT EXISTS `contents` (
  `usrId` int(11) NOT NULL,
  `topicsId` int(11) NOT NULL,
  `content` text NOT NULL,
  `comment` text NOT NULL,
  `nfo` text NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Contenu de la table `contents`
--


-- --------------------------------------------------------

--
-- Structure de la table `topics`
--

CREATE TABLE IF NOT EXISTS `topics` (
  `title` varchar(255) NOT NULL,
  `content` varchar(255) NOT NULL,
  `nfo` varchar(255) NOT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

--
-- Contenu de la table `topics`
--


-- --------------------------------------------------------

--
-- Structure de la table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `login` varchar(11) NOT NULL,
  `pass` varchar(11) NOT NULL,
  `nfo` varchar(255) NOT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

--
-- Contenu de la table `user`
--

un script d'installation pourrait être :

 Fichier : _install.php
<?php
/* install tables

*/

require_once "./config.inc.php";
require_once LIB."Request.cla.php";
require_once LIB."Connectivity.cla.php";

if(!(new Connectivity($cnx)))
{
	// Créer la base de données
	Request::SQL($cnx,'CREATE DATABASE IF NOT EXISTS miniForum;');

	// table de contenu
	Request::SQL($cnx,'CREATE TABLE IF NOT EXISTS `contents` (
	  `usrId` int(11) NOT NULL,
	  `topicsId` int(11) NOT NULL,
	  `content` text NOT NULL,
	  `comment` text NOT NULL,
	  `nfo` text NOT NULL
	) ENGINE=MyISAM DEFAULT CHARSET=latin1;');

	// table de sujets
	Request::SQL($cnx,'CREATE TABLE IF NOT EXISTS `topics` (
	  `title` varchar(255) NOT NULL,
	  `content` varchar(255) NOT NULL,
	  `nfo` varchar(255) NOT NULL,
	  `id` int(11) NOT NULL AUTO_INCREMENT,
	  PRIMARY KEY (`id`)
	) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;');

	// table des utilisateurs
	Request::SQL($cnx,'CREATE TABLE IF NOT EXISTS `users` (
          `login` varchar(11) NOT NULL,
          `pass` varchar(11) NOT NULL,
          `nfo` varchar(255) NOT NULL,
          `id` int(11) NOT NULL AUTO_INCREMENT,
          PRIMARY KEY (`id`)
        ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;');
}

?>

Conclusion

modifier

Cette façon de coder n'est pas la plus élégante et ne vise pas l'excellence. Bien que l'approche modulaire accroisse la quantité de code, elle a cependant l'avantage d'être lisible pour les longs développements. L'approche itérative et incrémentale de la méthodologie RUP tire fortement parti du développement modulaire.

À faire... 


  • une vue
  • un frameset variable
  • des sujets illimités
  • des catégories illimités
  • un système de classement
  • un système d'administration
  • un système d'authentification
  • un espace myAccount


NICE TO HAVE :

  • tout automatiser (censure / délation / ..)
  • mailer
  • BO admin