[Mis à jour] Créer un site d`entreprise de A à Z 3/3 : L’administration en PHP/MySQL
Design Spartan (Gaétan Weltzer) clôt ce tutoriel de création de site par le développement de l’administration en PHP/MySQL qui a été mis à jour avec un code optimisé.
L’objectif de ce tutoriel assez long est d’offrir un cas pratique avec une réflexion derrière. En situation réelle pour une entreprise, comment se passe la réalisation d’un site Internet de présentation ? Par où commence-t-on et comment finit-on, voici ce que nous allons voir ensemble. Mais tout d’abord, voici les captures d’écran de l’administration terminée et dynamique de cette troisième partie :
Captures d’écran de l’administration fonctionnelle de Real Tea
A lire avant de commencer
Plutôt que de faire un simple tutoriel de webdesign, je souhaite vous emmener dans la création d’un site Internet pour une entreprise fictive de A à Z : de la phase de réflexion jusqu’à la mise en ligne du site en passant par le webdesign, l’intégration et le développement. Néanmoins pour ce long exercice, nous ne nous pencherons dans la phase de réalisation que sur la page d’accueil étant donné que les autres pages sont simplement déclinées de celle-ci. Ainsi je parlerais des autres pages sans voir en détail le webdesign ou l’intégration.
Pour cet exercice, je vais vous montrer le procédé de création d’un site-vitrine qui est à peu près le même pour la majorité des entreprises souhaitant présenter leur activité et entrer en contact avec de potentiels clients. Pour tout de même partir dans l’originalité et montrer comment on peut s’adapter au cas par cas (notamment en matière de webdesign), j’ai décidé de réaliser le site d’une entreprise de vente de thé de qualité qui possède plusieurs boutiques en France. Le but de ce tutoriel est de partir de cet exemple précis (que vous ne rencontrerez probablement jamais) pour vous apporter des connaissances, des techniques et une méthodologie propre à la plupart des sites web, que ce soit en webdesign, en intégration, en développement ou en gestion de projet.
Page du tutoriel – ce qui a été crée dans Photoshop puis intégré en HTML5/CSS3 dans les précédentes parties
Ce tutoriel est découpé en 3 parties :
- La réflexion puis le webdesign : élaboration de la charte graphique et du design du site Internet
- Le développement PHP/MySQL des front et back office (administration)
3/3 : L’administration en PHP/MySQL
Cette troisième et dernière partie couvre les bases d’une administration à savoir :
- créer la base de données
- créer la page d’authentification
- ajout / suppression d’une actualité- ajout / suppression d’une page du site
- affichage dynamique sur la page d’accueil (en front office) des dernières actualités
- récupération des adresses emails sur l’accueil pour la newsletter
Ces quelques points seront suffisants pour comprendre le fonctionnement et ce qui est nécessaire à un site-vitrine administrable par une tierce personne. L’exemple est ici simple et basique pour ne pas se perdre dans les détails et éviter un tutoriel interminable. Cela vous permettra de réaliser des sites avec un espace d’administration et l’ajout / suppression de contenu dans une base de données et enfin de l’afficher sur la partie visible du site, aussi appelée front office.
NOTE : Le tutoriel a été mis à jour (en janvier 2013) avec un code beaucoup plus optimisé. Je remercie Samy, notre développeur professionnel, pour son coup de main sur cette troisième partie du tutoriel !
1. Redirection d’index.php
Le premier fichier que le visiteur verra en se connectant au site est bien entendu le fichier index. Pour notre administration, il ne contient que quelque lignes qui vont en fait rediriger l’utilisateur vers le formulaire de connexion :
<?php
header('Location: connexion.php'); # Redirection
exit();
?>
2. Créer la base de données
Que ce soit sur un serveur en ligne de votre hébergeur ou en local à l’aide de Wamp, la procédure est la même, passant par PhpMyAdmin.
Plutôt que de créer les tables une à une, nous sommes extrêmement généreux chez Living Tuts en vous donnant la base de donnée « realtea » déjà crée et remplie !
Depuis votre navigateur préféré, accédez donc à PhpMyAdmin. Allez dans l’onglet « Importer » pour créer automatiquement la base de données et la remplir. Cliquez sur « Parcourir » et choisissez le fichier « database.sql » qui n’est autre qu’un fichier texte contenant les requêtes nécessaires à la création et au remplissage des tables les unes après les autres. Vous pouvez l’ouvrir pour y trouver les requêtes nécessaires à la création des tables, tout est expliqué juste en-dessous. Une fois le fichier sélectionné, cliquez sur « Exécuter » et c’est terminé ! Vous n’avez plus rien à faire.
Normalement un message de confirmation a dû apparaître et vous annoncer que les tables ont été ajoutées.
Aller plus loin : les requêtes SQL expliquées
Depuis l’accueil de PhpMyAdmin (soit dans l’onglet Bases de données), créez la base de données en rentrant son nom « realtea ». Ne vous trompez pas dans le nom de la base, sinon il faudra penser à le changer dans le fichier de connexion à la base de données. Choisissez ensuite dans la liste déroulante l’interclassement « utf8_general_ci » qui est l’encodage standard, comme pour le format des fichiers des pages et le charset dans la balise meta des pages pour ne pas se faire chier avec les problèmes récurents d’accents.
Votre base est crée ! C’est aussi simple que ça ! Mais elle est vide. Oh.
La création des 3 tables n’a rien de compliqué mais quelques spécificités entrent en jeu, voici les requêtes permettant leur création. Chaque champ est explicité en-dessous.
Table news
CREATE TABLE IF NOT EXISTS `news` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(150) NOT NULL, `text` text NOT NULL, `date` datetime NOT NULL, `valid` tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
[id]
C’est l’identifiant primaire de la table donc il est en auto incrémentation et non signé pour doubler le nombre de possibilités comme il n’y a pas d’id négatif.
smallint signed => – 32 767 à 32 767
smallint unsigned => 0 à 65 535 ( De quoi faire quelques news… )
[title]
Varchar 150 caractères ou plus il faut voir si on va avoir des titres concis ou un paragraphe entier. A moduler selon les besoins.
[-text]
Format Text ( pas de limite de taille ) dans la limite du raisonnable, ça prend de la place mais cela laisse le choix au niveau du content.
[date]
Le meilleur format pour travailler facilement sur des filtre de recherche ou des formatage de résultat dans les requêtes.
[valid]
Booléen (1 valide, 0 non valide) pour ne jamais avoir à supprimer une entrée ( par défault à 1).Ceci est important à noter, par exemple lorsque vous supprimez une actualité, vous ne l’effacez pas de la base de données mais son champ valid est uniquement passé à 0. Ainsi cela évite les erreurs irrécupérables de suppression de données ou encore de hacking.
Table users
CREATE TABLE IF NOT EXISTS `users` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `login` varchar(150) NOT NULL, `pass` varchar(50) NOT NULL, `mail` varchar(150) NOT NULL, `token` varchar(50) NOT NULL, `token_date` datetime NOT NULL, `valid` tinyint(1) NOT NULL DEFAULT ’1', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; <pre>
[id]
Comme au-dessus.
[login]
Comme au-dessus.
[pass]
Cryptage md5 du mot de passe 32 caractères.
[mail]
Utile pour récupérer le mot de passe en cas de perte.
[valid]
Comme au-dessus.
Table newsletter
CREATE TABLE IF NOT EXISTS `newsletter` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, `mail` varchar(150) NOT NULL, `valid` tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
[id]
Comme au-dessus.
[mail]
Comme au-dessus.
[token]
Utile pour enregistrer le token de connection.
[token_date]
Utile pour enregistrer la date du token de connection.
[valid]
Comme au-dessus.
Connexion à la base de données
Pour la suite du tutoriel, nous allons créer une page « idents.php » qui va vous permettre de vous connecter à votre base de données. Nous allons utiliser PDO qui est une interface arrivée avec PHP 5 permettant de gérer toutes les opérations sur une base de données. L’avantage de PDO est qu’il permet d’écrire un code générique qui utilisera exactement les mêmes méthodes PHP quelque soit le SGBD (Système de Gestion de Base de Données) utilisé. Vous retrouverez la documentation associée ici : http://php.net/manual/en/book.pdo.php
Voici idents.php :
<?php
session_start(); # Ouverture des sessions
define('HOST', 'localhost');
define('USER','root');
define('PASSWORD','');
define('BDD','realtea');
define('PORT','3306');
try
{
$bdd = new PDO('mysql:host='.HOST.';port='.PORT.';dbname='.BDD, USER, PASSWORD);
}
catch(Exception $err)
{
die('erreur ['.$err->getCode().'] '.$e->getMessage());
}
?>
3. La page d’authentification
Comme pour toute administration, il faut un minimum de sécurité. La fameuse page d`identification est un classique duquel on ne se dérobe plus.
Créez un nouveau fichier PHP. Notre gentil développeur a pris soin de commenter le code. Dans les grandes lignes nous avons une partie HTML qui correspond au formulaire de connexion puis une partie en PHP au début qui n’intervient que si le formulaire a été soumis. On teste alors les données entrées (login et mot de passe) avec celles de la base de données et si tout est bon, on redirige vers la page d’accueil de l’administration, sinon on peut ajouter le comportement que l’on souhaite (message d’erreur…).
Il y a trois choses à noter pour la sécurité :
- la première est la protection contre les injections SQL (cf code commenté en-dessous)
- les mots de passe sont encryptés en md5 pour augmenter la sécurité
- si la mot de passe est bon, on commence par créer un cookie pour garder la session ouverte. La durée de ce cookie est d’une heure, une durée relativement court vu qu’il s’agit d’une interface d’administration.
<?php
include_once 'idents.php';
if(isset($_POST['login'], $_POST['mdp'])) # Si le formulaire est soumis
{
if (!empty($_POST['login']) && !empty($_POST['mdp']))
{
$login = $_POST['login']; # Protection des Injection SQL ect...
$mdp = sha1($_POST['mdp']);
$login_q = $bdd->prepare("SELECT * FROM users WHERE login = :login AND pass = :mdp AND valid = '1'");
$login_q->execute(array(
'login' => $login,
'mdp' => $mdp
));
if($login_q->fetchColumn() > 0) # Si login pass et valid ok
{
$user = $login_q->fetch(PDO::FETCH_OBJ);
$token = sha1(uniqid().$user->id.sha1(uniqid()));
setcookie('token', $token, time()+3600); # Création des cookies
$user_id = $user->id;
$setToken_q = $bdd->prepare("UPDATE users SET token = :token, token_date = NOW() WHERE id = :user_id");
$setToken_q->execute(array(
'token' => $token,
'user_id' => $user_id
));
$token = null;
$_SESSION['login'] = $user->login; # Création des sessions
header('Location: actu.php'); # Redirection
exit();
}
else # Sinon
{
# Login ou Mot de passe incorrect
}
}
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Real Tea : Tutoriel pour Living Tuts - fr.livingtuts.com</title>
<link rel="stylesheet" href="style.css" type="text/css" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<!--[if lte IE 8]>
<link rel="stylesheet" type="text/css" media="all" href="ie8.css"/><! [endif]-->
<!--[if lte IE 7]>
<link rel="stylesheet" type="text/css" media="all" href="ie7.css"/>
<script src="js/IE8.js" type="text/javascript"></script><![endif]-->
</head>
<body>
<!--[if IE]><div id="fond_ie"><! [endif]-->
<nav id="menu_top">
<ul>
<li><a href="#">Actualités</a></li>
<li><a href="#">Pages</a></li>
<li><a id="deco" href="logout.php">Se déconnecter</a></li>
</ul>
</nav>
<div></div>
<div>
<header id="header_top">
<a id="logo" href="#">
<h1><img src="images/logo.png" alt="Real Tea : société spécialisée dans le thé rare de qualité"/></h1>
</a>
</header>
<section id="connexion">
<form method="post" action="connexion.php">
<label for="id">Identifiant</label>
<input id="login" name="login" type="text" required /> <!-- Remplir ce champ est requis -->
<br/>
<label for="mdp">Mot de passe</label>
<input id="mdp" name="mdp" type="password" required /> <!-- Remplir ce champ est requis -->
<a href="#" id="pwd_oubli" >Mot de passe oublié ?</a>
<input type="submit" value="Connexion">
</form>
</section>
<div></div>
<footer id="footer_site">
<aside>
<p>Retrouvez-nous aussi sur : </p><p style="float:left;"><a href="#"><img src="images/fb.png" alt="Joignez-nous sur Facebook"/></a> <a href="#"><img src="images/twitter.png" alt="Joignez-nous sur Twitter"/></a></p>
</aside>
<p id="copyright">© Gaétan Weltzer Tous droits réservés - tutoriel pour Living Tuts : <a href="http://www.livingtuts.com">www.livingtuts.com</a></p>
<div></div>
</footer>
</div>
<!--[if lte IE 8]></div> <! [endif]-->
</body>
</html>
4. Ajouter/supprimer une actualité
Rappelons-nous du tout premier tutoriel à l’étape de réflexion. Nous avions décidé très en amont que les utilisateurs (notre client fictif Real Tea) pourrait ajouter dynamiquement du contenu. Il s’agit des actualités présentes sur le site ainsi que de la création de nouvelles pages qui pourraient par exemple être : « Comment préparer nos thés » ou encore « Notre équipe », etc… Sur la page d’administration des actualités nous avons 4 choses pour rester simple et concis pour le tutoriel :
- ajout d’une nouvelle actu en remplissant un formulaire
- liste des actualités déjà présentes sur le site
- suppression d’une actualité listée
- redirection vers une actu (bêtement, un lien « lire l’actualité » qui renvoie vers la page de l’actualité)
Pour ce qui est des explications, je n’ai pas grand chose à dire, tout est commenté ! En une ligne, on teste au tout début si on a reçu le paramètre GET « delete », si tel est le cas, on supprime l’actualité qui a été supprimée. Si l’utilisateur a cliqué sur « Créer une actualité », on récupère les données (date, titre, texte) et on les rentre dans la base. Et enfin on cherche dans la base les actualités à afficher sous le formulaire de la page.
<?php
include_once 'idents.php';
date_default_timezone_set('Europe/Paris'); # Définition du Time Zone
$token = '';
if(isset($_COOKIE['token']) && !empty($_COOKIE['token']))
$token = $_COOKIE['token']; # Récupération des Cookies & Ou Sessions
$token = $token; # Protection des Injection SQL ect...
$login_q = $bdd->prepare("SELECT * FROM users WHERE token = :token AND valid = '1'");
$login_q->execute(array(
'token' => $token
));
if($login_q->fetchColumn() == 0) # Si login pass et valid nok
{
header('Location: connexion.php'); # Redirection
exit();
}
if(isset($_GET['delete']) && !empty($_GET['delete'])) # Si le paramètre delete est spécifié dans l'URL
{
$id = $_GET['delete']; # Protection des Injection SQL ect...
$delete_q = $bdd->prepare("UPDATE news SET valid = '0' WHERE id = :id");
$delete_q->execute(array(
'id' => $id
));
}
if(isset($_POST['date1'], $_POST['titre'], $_POST['desc'])) # Création d'une news
{
if(!empty($_POST['date1']) && !empty($_POST['titre']) && !empty($_POST['desc']))
{
$date = date('Y-m-d H:i:s', $_POST['date1']); # Protection des Injection SQL ect...
$title = $_POST['titre'];
$text =$_POST['desc'];
$insert_q = $bdd->prepare("INSERT INTO news VALUES ('', :title, :text, :date, '1')"); # Insertion dans la table d'une nouvelle news
$insert_q->execute(array(
'text' => $text,
'title' => $title,
'date' => $date
));
}
}
$news = array();
$selectAll_q = $bdd->prepare("SELECT id, title, text, DATE_FORMAT(date, '%b') AS date_b, DATE_FORMAT(date, '%d') AS date_d, valid FROM news WHERE valid = '1'"); # Selection de toutes les news valides
$selectAll_q->execute();
while($result = $selectAll_q->fetch(PDO::FETCH_ASSOC))
{
$news[] = $result; # Replissage du tableau avec ces valeurs
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Real Tea : Tutoriel pour Living Tuts - fr.livingtuts.com</title>
<link rel="stylesheet" href="style.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="inc/css/calendar-eightysix-v1.1-vista.css" media="screen" /> <!-- Template du calendar JS -->
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<!--[if lte IE 8]>
<link rel="stylesheet" type="text/css" media="all" href="ie8.css"/><! [endif]-->
<!--[if lte IE 7]>
<link rel="stylesheet" type="text/css" media="all" href="ie7.css"/>
<script src="js/IE8.js" type="text/javascript"></script><![endif]-->
<script type="text/javascript" src="inc/js/mootools-1.2.4-core.js"></script> <!-- Frameworks JS Mootools Core -->
<script type="text/javascript" src="inc/js/mootools-1.2.4.4-more.js"></script> <!-- Frameworks JS Mootools More -->
<script type="text/javascript" src="inc/js/calendar-eightysix-v1.1.js"></script> <!-- Plugin Mootools Calendar Eightysix -->
<script type="text/javascript">
// Très bonne doc du calendar : http://dev.base86.com/scripts/mootools_javascript_datepicker_calendar_eightysix.html
window.addEvent('domready', function()
{
MooTools.lang.set('fr-FR', 'Date', {
months: ['Janvier', 'Févrié', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Decembre'],
days: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
dateOrder: ['date', 'month', 'year', '/']
});
MooTools.lang.setLanguage('fr-FR');
new CalendarEightysix('date1',
{
'theme': 'vista',
'defaultView': 'day',
'startMonday': true,
'format': '%d/%m/%Y',
'createHiddenInput': true,
'hiddenInputName': 'date2',
'disallowUserInput': true
});
});
</script>
</head>
<body>
<!--[if IE]><div id="fond_ie"><! [endif]-->
<nav id="menu_top">
<ul>
<li><a href="actu.php">Actualités</a></li>
<li><a href="page.php">Pages</a></li>
<li><a id="deco" href="#">Se déconnecter</a></li>
</ul>
</nav>
<div></div>
<div>
<header id="header_top">
<a id="logo" href="#">
<h1><img src="images/logo.png" alt="Real Tea : société spécialisée dans le thé rare de qualité"/></h1>
</a>
</header>
<section id="actu">
<header>
<h2>Ajouter / Supprimer une actualité</h2>
</header>
<p>Ici vous pouvez ajouter ou supprimer une actualité. Celle-ci apparaîtra automatiquement sur la page d'accueil et pourra ensuite être lue en entier lorsque le visiteur clique dessus.</p>
<form method="post" action="actu.php">
<label for="date1">Date</label>
<input id="date1" name="date1" type="date" required /> <!-- Remplir ce champ est requis -->
<br/>
<label for="titre">Titre de l'actualité</label>
<input id="titre" name="titre" type="text" required /> <!-- Remplir ce champ est requis -->
<br/>
<label for="desc">Description <em>(limité à 1000 caractères - il est conseillé de rester synthétique dans la description)</em></label>
<textarea id="desc" name="desc"></textarea> <!-- Remplir ce champ est requis -->
<br/>
<input type="submit" value="Créer l'actualité">
</form>
<header id="header_liste_actu">
<h2>Actualités déja publiées</h2>
</header>
<!-- boucle affichant les dernières actus -->
<ul id="news">
<?php
foreach($news as $nw) # Boucle qui affiche les news
{
echo '
<li>
<article>
<header>
<h3><a href="#">'.$nw['title'].'</a></h3>
</header>
<footer>
<time datetime="2011-01-01" pubdate>'.$nw['date_d'].' <span><br/>'.$nw['date_b'].'</span></time> <!-- l\'atribut booléen pubdate signifie que le "time" spécifié est bien celui de l\'article au cas où il y aurait plusieurs <date> dedans-->
</footer>
<div>
<p>'.$nw['text'].'</p>
<div>
<p><a href="#"> Voir l\'actualité</a></p>
<p><a href="actu.php?delete='.$nw['id'].'">Supprimer</a></p>
</div>
</div><!-- /.entry-content -->
</article>
</li>';
}
?>
</ul>
</section>
<div></div>
<footer id="footer_site">
<aside>
<p>Retrouvez-nous aussi sur : </p><p style="float:left;"><a href="#"><img src="images/fb.png" alt="Joignez-nous sur Facebook"/></a> <a href="#"><img src="images/twitter.png" alt="Joignez-nous sur Twitter"/></a></p>
</aside>
<p id="copyright">© Gaétan Weltzer Tous droits réservés - tutoriel pour Living Tuts : <a href="http://www.livingtuts.com">www.livingtuts.com</a></p>
<div></div>
</footer>
</div>
<!--[if lte IE 8]></div> <! [endif]-->
</body>
</html>
5. Ajouter/supprimer une page
Cette interaction fonctionne en fait exactement comme pour les actualités. On peut en ajouter ou en supprimer, la requête ainsi que la page possèdent la même structure.
<?php
include_once 'idents.php';
date_default_timezone_set('Europe/Paris'); # Définition du Time Zone
$token = '';
if(isset($_COOKIE['token']) && !empty($_COOKIE['token']))
$token = $_COOKIE['token']; # Récupération des Cookies & Ou Sessions
$token = $token; # Protection des Injection SQL ect...
$login_q = $bdd->prepare("SELECT * FROM users WHERE token = :token AND valid = '1'");
$login_q->execute(array(
'token' => $token
));
if($login_q->fetchColumn() == 0) # Si login pass et valid nok
{
header('Location: connexion.php'); # Redirection
exit();
}
if(isset($_GET['delete'])) # Si le paramètre delete est spécifié dans l'URL
{
if (!empty($_GET['delete']))
{
$id = $_GET['delete']; # Protection des Injection SQL ect...
$delete_q = $bdd->prepare("UPDATE pages SET valid = '0' WHERE id = :id");
$delete_q->execute(array(
'id' => $id
));
}
}
if(isset($_POST['titre'], $_POST['desc'])) # Création d'une page
{
if (!empty($_POST['titre']) && !empty($_POST['desc']))
{
$title = $_POST['titre']; # Protection des Injection SQL ect...
$text = $_POST['desc'];
$insert_q = $bdd->prepare("INSERT INTO pages VALUES ('', :title, :text, '1')");
$insert_q->execute(array(
'title' => $title,
'text' => $text
));
}
}
$pages = array();
$selectAll_q = $bdd->prepare("SELECT * FROM pages WHERE valid = '1'"); # Selection de toutes les pages valides
$selectAll_q->execute();
while($result = $selectAll_q->fetch(PDO::FETCH_ASSOC))
{
$pages[] = $result; # Replissage du tableau avec ces valeurs
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Real Tea : Tutoriel pour Living Tuts - fr.livingtuts.com</title>
<link rel="stylesheet" href="style.css" type="text/css" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<!--[if lte IE 8]>
<link rel="stylesheet" type="text/css" media="all" href="ie8.css"/><! [endif]-->
<!--[if lte IE 7]>
<link rel="stylesheet" type="text/css" media="all" href="ie7.css"/>
<script src="js/IE8.js" type="text/javascript"></script><![endif]-->
</head>
<body>
<!--[if IE]><div id="fond_ie"><! [endif]-->
<nav id="menu_top">
<ul>
<li><a href="actu.php">Actualités</a></li>
<li><a href="page.php">Pages</a></li>
<li><a id="deco" href="logout.php">Se déconnecter</a></li>
</ul>
</nav>
<div></div>
<div>
<header id="header_top">
<a id="logo" href="#">
<h1><img src="images/logo.png" alt="Real Tea : société spécialisée dans le thé rare de qualité"/></h1>
</a>
</header>
<section id="actu">
<header>
<h2>Ajouter / Supprimer une page</h2>
</header>
<p>Ici vous pouvez ajouter ou supprimer une page. Celle-ci apparaîtra automatiquement sur la page d'accueil et pourra ensuite être lue en entier lorsque le visiteur clique dessus.</p>
<form method="post" action="page.php">
<label for="titre">Titre de la page</label>
<input id="titre" name="titre" type="text" required /> <!-- Remplir ce champ est requis -->
<br/>
<label for="desc">Description <em>(limité à 1000 caractères - il est conseillé de rester synthétique dans la description)</em></label>
<textarea id="desc" name="desc"></textarea> <!-- Remplir ce champ est requis -->
<br/>
<input type="submit" value="Créer la page">
</form>
<header id="header_liste_actu">
<h2>Pages déja crées</h2>
</header>
<!-- boucle affichant les dernières actus -->
<ul id="news">
<?php
foreach ($pages as $page) # Boucle qui affiche les pages
{
echo '
<li>
<article>
<header>
<h3><a href="#">'.$page['title'].'</a></h3>
</header>
<div>
<p>'.$page['text'].'</p>
<div>
<p><a href="#"> Voir la page</a></p>
<p><a href="actu.php?delete='.$page['id'].'">Supprimer</a></p>
</div>
</div><!-- /.entry-content -->
</article>
</li>';
}
?>
</ul>
</section>
<div></div>
<footer id="footer_site">
<aside>
<p>Retrouvez-nous aussi sur : </p><p style="float:left;"><a href="#"><img src="images/fb.png" alt="Joignez-nous sur Facebook"/></a> <a href="#"><img src="images/twitter.png" alt="Joignez-nous sur Twitter"/></a></p>
</aside>
<p id="copyright">© Gaétan Weltzer Tous droits réservés - tutoriel pour Living Tuts : <a href="http://www.livingtuts.com">www.livingtuts.com</a></p>
<div></div>
</footer>
</div>
<!--[if lte IE 8]></div> <! [endif]-->
</body>
</html>
6. Se déconnecter
Il n’y a pas grand chose à dire sur cette partie. On détruit la session ainsi que le cookie puis on redirige vers l’index.
<?php
include_once 'idents.php';
$token = '';
if(isset($_COOKIE['token']) && !empty($_COOKIE['token']))
$token = $_COOKIE['token']; # Récupération des Cookies & Ou Sessions
$insert_q = $bdd->prepare("UPDATE users SET token = '', token_date = '' WHERE token = :token AND valid = '1'"); # Insertion de l'adresse email dans la table
$insert_q->execute(array(
'token' => $token
));
session_destroy();
$_SESSION = array();
setcookie('token', '', time()-3600); # Destruction des cookie
header('Location: connexion.php'); # Redirection
?>
7. On rend le site dynamique dans sa partie visible
A ce stade, on peut ajouter ou supprimer des contenus dans la base de données, mais ils ne sont pas encore visibles sur le front office ! Cela signifie que les visiteurs du site ne voient toujours que le texte écrit en dur en HTML à l’étape 2 du tutoriel (l’intégration HTML). Il faut donc rajouter un peu de PHP dans la partie visible du site pour qu’il cherche les bonnes informations dans la base de données à l’aide d’une requête puis qu’il l’affiche là où nous le voulons depuis le départ. Cela signifie qu’il faudra veiller à garder la même structure dans la page HTML en ajoutant le contenu dynamique dans la bonne balise au bon endroit pour ne pas perdre une classe ou un id et ainsi avoir un affichage erroné car aucun CSS n’est associé au texte.
Première chose à faire : Reprenez les fichiers du front office (ne vous trompez pas !) et trouvez index.html. Pour que notre script marche, il faut transformer ce fichier html en fichier PHP, changer juste l’extension afin d’avoir « index.php ».
Note : dans les fichiers du tutoriel, le fichier index du site visible se nomme « index_front.php ».
Ensuite nous allons ajouter du php au tout début avant la première ligne :
<?php
include_once 'idents.php';
if(isset($_POST['email'])) # Si le formulaire de newsletter est soumis
{
if (!empty($_POST['email']))
{
$email = $_POST['email']; # Protection des Injection SQL ect...
$insert_q = $bdd->prepare("INSERT INTO newsletter VALUES('', :email, '1')"); # Insertion de l'adresse email dans la table
$insert_q->execute(array(
'email' => $email
));
}
}
?>
Si vous avez suivi, nous nous connectons à la base de données puis ensuite on teste si la variable « email » a été envoyé. Si tel est le cas, cela veut dire qu’un utilisateur a entré son adresse email pour s’inscrire à la newsletter. Son adresse est donc entrée dans la table « newsletter » de notre base.
NB : Dans le cadre du tutoriel, nous partons du principe que l’input HTML5 de type « email » suffit à prévenir au cas où l’utilisateur rentre du texte qui n’est pas sous forme d’un email, par exemple test@test.com. En condition réelle, pensez à rajouter un test en PHP avant de l’entrer dans la base de données.
Ensuite, on récupère les trois dernières actualités valides. Il ne nous reste plus qu’à les afficher là où il faut, c’est-à -dire dans le bloc « actualités ».
<aside id="news">
<header>
<h2>ACTUALITES</h2>
</header>
<ul>
<?php
$count = count($news); # Nombre de news
for($i=0;$i<$count;$i++) # Boucle qui affiche les news
{
echo '
<li>
<article>
<header>
<h3><a href="#">'.$news[$i]['title'].'</a></h3>
</header>
<footer>
<time datetime="2011-01-01" pubdate>'.$news[$i]['date_d'].' <span><br/>'.$news[$i]['date_b'].'</span></time> <!-- l\'atribut booléen pubdate signifie que le "time" spécifié est bien celui de l\'article au cas où il y aurait plusieurs <date> dedans-->
</footer>
<div>
<p>'.$news[$i]['text'].'</p>
<p><a href="#">Lire la suite</a></p>
</div><!-- /.entry-content -->
</article>
</li>';
}
?>
</ul>
</aside>
Toute dernière chose : pour être sûr que votre formulaire pour la newsletter marche bien, veillez à avoir rempli l’attribut action avec « index.php » comme il suit :
<form method="post" action="index.php"> <input name="email" type="email" placeholder="Mon adresse email" required> <!-- Remplir ce champ est requis --> <br/> <input type="submit" value="Je m'inscris"> </form>
Et voilà , nous avons fait le tour de cet énorme tutoriel !
Pour résumer nous avons vu ensemble :
- la partie de réflexion et de début de gestion de projet afin de définir les besoins et contraintes du site
- le webdesign, création de la charte graphique et ergonomie
- intégration en HTML5/CSS3
- développement de l’administration permettant à Real Tea de se connecter à un back office pour ajouter/supprimer actualités et pages puis de les afficher dynamiquement dans la section visible du site ainsi que l’enregistrement de l’email de l’utilisateur pour la newsletter.
Je rappelle encore une dernière fois qu’il s’agit là de la base d’un CMS. Cette administration de site pourrait être développée sans fin encore et encore au niveau des contenus, des messages, des fonctionnalités, de la sécurité, ajouter de l’AJAX, etc… On pourrait en faire un livre ! Néanmoins il vous apporte les connaissances nécessaires à l’élaboration d’une petite administration, après c’est à vous d’aller plus loin ! J’espère comme toujours qu’il répondra à vos attentes et qu’il boucle ce très long tutoriel comme il se doit. Ce fut pour moi un plaisir de rédiger ce tutoriel en 3 parties, bien qu’éprouvant ! J’espère vous avoir enrichi par ma méthode de travail professionnelle et la technique ainsi que les connaissances nécessaires derrière.
Je remercie Samy, notre développeur professionnel, pour son coup de main sur cette troisième partie du tutoriel !
Je vous dit à bientôt pour un prochain tutoriel !
23 Comments to “[Mis à jour] Créer un site d`entreprise de A à Z 3/3 : L’administration en PHP/MySQL”
Laisser un commentaire
Tutoriels Populaires
- Créer un site d`entreprise de A à Z 2/3 : Intégration HTML5 / CSS3
- Résultat du sondage pour le prochain tutoriel de Spartan
- Créez votre thème WordPress en intégrant votre design
- Créer un site d’entreprise de A à Z 1/3 : Réflexion & Webdesign
- Créer un webdesign e-commerce – 3/3 Intégration HTML5/CSS3
Mes Tutoriels Favoris
Vous devez être loggué pour pouvoir ajouter des tutoriels à cette liste.
Connexion
Ecrivez pour nous
- Vous voulez aider la communauté et partager votre savoir ?
- Vous voulez acquérir de la visibilité sur Internet ?









Bonjour,
Merci pour ce super tuto, peux on avoir les fichier source ?
Nous allons les ajouter dans les prochains jours.
Bonjour,
J’ai suivi votre tutoriel, vraiment très beau, vraiment très intéressant,
je m’en suis « inspiré » pour réaliser le site ‘maquette’ pour un artisan :
http://bois.assistance-informatique-montlucon.com
le site est pas terminé, il reste encore de l’intégration pour que ça passe avec tous les navigateurs (IE6 etc…), nom de domaine, etc…
J’ai utilisé la création d’article pour créer des Meubles,
l’artisan peut entrer dans une zone sécurisée,
et changer ses Meubles (ajouter ou supprimer) avec le titre, la photo, la description
puis les meubles seront automatiquement affichés dans la page des meubles,
dynamiquement en php.
merci
bonne continuation
sunny
Bonsoir et merci mille fois pour ce tutoriel !! Je pensais pas en trouver un aussi complet sur le net
Par contre, je ne trouve pas la base de donnée de Real Tea, serait t’il possible de l’avoir ?
Merci beaucoup et continuer les gars ! ( et les filles ) :p
C’est trinks ^^
Merci pour la suite du tutoriel.
Pour la sécurité du mot de passe, il faut peut être préciser que le hashage en md5 est bien, mais n’est plus suffisant ? Si quelqu’un arrive à récupérer la base de données, il peut retrouver quasi tous les mots de passe relativement rapidement.
Par contre, en faisant du hashage du type sha1, mélanger avec du md5 et l’ajout de sel (dans un ordre que personne ne connait, sauf le codeur), ça devient BIEN plus compliquer à faire du reverse ingeneering, et donc le mot de passe est vraiment super sécurisé.
Merci pour ces informations Bouv. Le tutoriel est bien sûr toujours améliorable et optimisable, cela peut être sans fin. C’est pourquoi nous l’avons orienté vers un niveau débutant d’ailleurs.
Bonjour,
je tiens à vous remercier pour ce trés bon tuto, complet et trés intéressant.
mais est ce que c’est possible de créer des pages dynamiquement en partant seulement de la page d’acceuil.
par exemple : index.php?page=1 ==>> index.php/page_id_1.php
merci de me répondre parceque ça fait un moment que je cherche la réponse.
Encore merci pour le tutoriel.
cordialement yacine.
Bonjour à tous,
Effectivement très bon tutoriel, complet, c’est rare….CONTINUER.
Il manque tout de même un page en php pour l’inscription, et une page pour le mot de passe oublié.
Salutations.
Oui on peut toujours clairement améliorer ce tutoriel, cela est sans fin, jusqu’à aboutir à un vrai CMS même.
Merci pour ton message !
Salut,
Magnifique tuto de Webdesign.
Je vais avoir du taf, car je suis débutant !…
Encore un grand Merci !
Amicalement,
Philippe
Merci pour ce commentaire qui fait plaisir !
Bonjour,
Superbe tuto, rien à redire si ce n’est qu’il n’y a toujours pas les fichiers sources pour la dernière partie :/
Mais bon on va essayer de patienter faute d’arriver à tout comprendre
Salut, les fichiers sont téléchargeables depuis presque un mois (en-haut de l’article).
Certes mais il n’y a pas le fichier database.sql comme annoncé dans le tuto
J’ajoute ce soir (ou demain) le fichier SQL au zip à télécharger.
Thanks, very good tutorials, Congratulations
Super tuto et j’adore votre site mais je voudrais savoir où se trouve la base de donnée « realtea » déjà crée et remplie je ne le trouve pas dans le dossier
Bonjour, j’ajoute ce soir (ou demain) le fichier SQL au zip à télécharger.
Bonsoir, petite piqure de rappel car le fichier database.sql n’est toujours pas dans le zip, et sinon j’ai essayé de faire de comprendre mais j’ai le même message que Ascore
Merci d’avance pour le fichier et encore merci pour ce superbe tuto qui m’a permis d’apprendre plein de choses
Bonjour j’ai un rpoblème quand je met la table user j’ai ce message
#1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’1′, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=’ at line 8
Je comprend pas d’où viens le problème pourriez vous m’aidé s’il vous plait ?
J’ai un problème, lorsque je me connecte avec les bons identifiants, il me redirige vers ma page de connexion. Cela doit être un problème de sessions et/ou de cookies mais j’ai copié le code à la lettre pour être sur.
Vous avez une solution ?
J’ai le même souci que toi … Si quelqu’un avais une solution ça serais cool
bonjour,
je viens de regarder le tuto, et en essayant les sources, ca mets des erreurs, connexion.php ??? dans les sources les pages sont appellés : livigntut1 …. quelles sont les correspondances avec connexion , logout etc ….
Merci d’avance.