Après une absence prolongée sur le blog (bac blanc) je reviens avec un tutoriel vidéo qui risque d’en intéresser plus d’un. Nous allons voir comment faire un système de news avec un flux RSS, le tout administrable depuis une page protégée par htaccess.
La vidéo est longue (1h20 min) car j’ai essayé d’être le plus précis possible pour vous proposer un système relativement complet. Avant de commencer, une petite description de ce que l’on va faire s’impose :
Le système pour afficher les news est découpée en 2 parties, une partie ou l’on affiche les descriptions des 5 dernières news (sur la page d’accueil du site par exemple) et une partie ou l’on affiche la news complète.
La page d’administration est elle aussi découpé en plusieurs parties. Pour résumé, on peut créer une news avec un système utilisant tinymce pour pouvoir mettre en page le texte correctement et une partie pour modifier et/ou supprimer les news déjà faites.
Et enfin, pour rester original et ne pas faire comme dans la plupart des tutoriels sur internet qui s’arrête ici, je vous montre comment faire un flux RSS pour proposer à vos visiteurs de s’abonner et pour optimiser le référencement de vos pages.
Tutoriel Vidéo : Système de news en PHP avec flux RSS
envoyé par zone-tuto. – Regardez plus de vidéos de science.
Bon, j’ai pas mal de trucs à préciser. Premièrement, et c’est quelque chose que j’ai longtemps cherché mais je n’en ai pas parlé dans le tutoriel, c’est qu’on pourrait ajouter un système de pagination. Surtout sur les pages d’administration, vous imaginez avoir 50 news d’un coup ?? J’ai vraiment beaucoup cherché et j’ai trouvé un système qui est très sympa, fait par un autre blogueur. Je l’utilise sur mon deuxième site, il est facile à mettre en place et je n’ai jamais eu de problème. Je précise que c’est un système de pagination complète du genre « 1 2 3 … 40 41″, pas comme ceux qu’on a l’habitude de voir qui ne sont pas top. Pour le script, alors voir l’article sur son blog.
Ensuite, second point : tinyMce. J’en parle énormément dans la vidéo, j’ai expliqué un peu son fonctionnement sans trop détailler parce que j’ai déjà fait un tutoriel. Je vous conseille d’aller le lire, c’est toujours un plus. Dans le même contexte, j’ai parlé d’une faille de sécurité (c’est expliqué dans le tutoriel sur tinymce) mais je vais en reparler un petit peu.
Pour faire simple, j’ai dit que tinyMCE nous protège des pirates qui essayeraient de mettre du code HTML directement. Or tinyMCE est en javascript, donc si le pirate désactive le javascript de son navigateur, tinyMCE n’apparait pas et donc ne protège pas le textarea. Dans notre cas, ce n’est pas spécialement grave puisque la page d’administration est protégée par htaccess et que normalement on est les seuls à y avoir accès. Une méthode pour parer à ça, c’est de faire le textarea en javascript, mais j’ai constaté que cela pose des problèmes dans le cas ou on modifie les news (je n’entre pas dans les détails …).
Dans la vidéo, j’ai parlé des htaccess et htpasswd qui protège le dossier admin par mot de passe. C’est essentiel, en effet quelqu’un qui aurait accès à la page d’administration pourrait supprimer/modifier toutes les news ! Je n’ai pas été très précis dans la vidéo, c’est pour cela que je vous recommande vivement de lire le tutoriel déjà présent sur le site du zéro.
Un autre petit détail, c’est que pour la première fois, j’ai choisie l’option « CURRENT_TIMESTAMP » dans la base de données. Je le précise pour ceux qui copie simplement les codes sans regarder la vidéo. Avec cette option, automatiquement la date se remplie à chaque nouvelle entrée sans qu’on ait besoin de le faire en php. C’est aussi pour cela que j’utilise la fonction « strtotime » qui permet de convertir une date en timestamp.
Bon je crois que je n’ai rien oublié, dans le cas contraire dites le. Voici les codes, je les ai commentés pour que vous puissiez comprendre. C’est long, mais ce n’est pas très compliqué, beaucoup de choses se répètent (notamment les requêtes). Rien ne vous empêche de les modifier, au contraire. Ce que je propose, c’est le fruit de mon raisonnement et je ne suis pas un pro en php. Donc si vous utilisez ces codes, faites quand même attention. (d’ailleurs si quelqu’un à un commentaire à faire dessus, je serai ravi de l’écouter).
1.Le ficher config.php qui contient toutes les variables pour se connecter à la BDD. C’est pratique, si un jour vous changez d’hébergeur, vous n’aurez que ce fichier à modifier.
<?php /* Identifiants pour se connecter à la BDD */ $adresse = 'localhost'; $nom = 'root'; $motdepasse = ''; $database = 'tutoriel'; ?> |
2. Le code de la page index qui permet d’afficher les news (j’ai aussi mis la ligne de code pour « déclarer » notre flux rss et avoir le logo dans la barre d’adresse).
<!-- Entre les balises head -->
<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="http://www.votresite.com/dossier/news/flux.php" />
<!-- ############# -->
<h1>Les dernières news !</h1>
<?php
/*
Connexion à la BDD
*/
require "config.php";
mysql_connect($adresse, $nom, $motdepasse);
mysql_select_db($database);
/*
Affichage d'une news en particulier
*/
if(isset($_GET['id'])){
$id = intval(htmlentities($_GET['id']));
/*
Si l'id !=0, intval renvoie quelque chose de bon
*/
if($id != 0){
$sql = 'SELECT * FROM news WHERE id='.$id.'';
$req = mysql_query($sql) or die(mysql_error());
$data = mysql_fetch_assoc($req);
echo '<h1>'.stripslashes($data['titre']).'</h1>';
echo '<em>'. date("d/m/Y G:i", strtotime($data['date'])).'</em>';
echo '<p>'.stripslashes($data['contenu']).'</p>';
}
/*
id ==0, intval renvoie certainement qqch de faux
*/
else
{
echo "Erreur";
}
}
/*
Listage des 5 dernières news
*/
else
{
$sql = 'SELECT * FROM news LIMIT 0,4';
$req = mysql_query($sql) or die(mysql_error());
while($data = mysql_fetch_assoc($req)){
?>
<h2><a href="index.php?id=<?php echo $data['id']; ?>"><?php echo stripslashes($data['titre']);?></a></h2>
<em><?php echo date("d/m/Y G:i", strtotime($data['date'])); ?></em>
<p><?php echo stripslashes($data['description']); ?></p>
<?php
}
}
?> |
3.Tout le code php de la page d’administration (le reste étant pour le design). J’ai essayé de commenter au maximum le code sans trop en mettre, j’espère que ça ira :
<h1 style="text-align:center;">Page d'administration</h1> <?php /* Connexion à la BDD */ require "../config.php"; mysql_connect($adresse, $nom, $motdepasse); mysql_select_db($database); /* Si une action est posté par l'url, on veut faire qqch, on fait un switch pour prévoir tout les cas : */ if(isset($_GET['action'])) { $action = addslashes(htmlentities($_GET['action'])); switch ($action){ /* Action = creer, on veut faire une nouvelle news */ case "creer": /* Si les variables sont déja posté, on les stockes dans la BDD */ if(isset($_POST['titre']) AND isset($_POST['description']) AND isset($_POST['contenu'])){ extract($_POST); $titre = addslashes(htmlentities($titre)); $description = addslashes($description); $contenu = addslashes($contenu); $sql = 'INSERT INTO news(titre, description, contenu) VALUES ("'.$titre.'", "'.$description.'", "'.$contenu.'")'; $req = mysql_query($sql) or die(mysql_error()); echo "<a href=\"admin.php\">Cliquez ici</a>"; } /* Les variables ne sont pas posté, on affiche le formulaire pour créer la news */ else { ?> <form method="post" action="admin.php?action=creer"> Titre : <br/><input type="text" name="titre" /><br/> Description :<br/><textarea name="description" class="mceEditor"></textarea><br/> Contenu :<br/><textarea name="contenu" class="mceEditor"></textarea><br/> <input type="submit" value="envoyer"/> </form> <?php } break; // creer /* Action = Gerer, on veut lister les news dans le but de les modifier/supprimer */ case "gerer": $sql = 'SELECT * FROM news'; $req = mysql_query($sql) or die(mysql_error()); echo "<ul>"; while($data = mysql_fetch_assoc($req)){ echo '<li>'.$data['titre'].' -- <a href="admin.php?action=modifier&id='.$data['id'].'">Modifier</a> -- <a href="admin.php?action=supprimer&id='.$data['id'].'">X</a></li>'; } echo "</ul>"; break; /* Action = Modifier, on veut modifier une news */ case "modifier": /* Si l'id existe, tout se passe bien : */ if(isset($_GET['id'])) { $id = intval(htmlentities($_GET['id'])); /* Si des données POST sont déja envoyer, il faut les stocké dans la BDD */ if(isset($_POST['titre']) AND isset($_POST['description']) AND isset($_POST['contenu'])){ extract($_POST); $titre = addslashes(htmlentities($titre)); $description = addslashes($description); $contenu = addslashes($contenu); $sql = 'UPDATE news SET titre="'.$titre.'", description="'.$description.'", contenu="'.$contenu.'" WHERE id='.$id.''; $req = mysql_query($sql) or die(mysql_error()); echo 'Ok, <a href="admin.php">cliquez ici</a> pour revenir'; } /* Les données POST n'existe pas, on recupère les données de la news pour les réafficher dans le formulaire */ else { $sql = 'SELECT * FROM news WHERE id='.$id.''; $req = mysql_query($sql) or die(mysql_error()); $data = mysql_fetch_assoc($req); ?> <form method="post" action="admin.php?action=modifier&id=<?php echo $data['id'];?>"> Titre : <br/><input type="text" name="titre" value="<?php echo $data['titre'];?>"/><br/> Description :<br/><textarea name="description" class="mceEditor"><?php echo $data['description'];?></textarea><br/> Contenu :<br/><textarea name="contenu" class="mceEditor"><?php echo $data['contenu'];?></textarea><br/> <input type="submit" value="envoyer"/> </form> <?php } } /* Si l'id n'existe pas, on a un problème, on peut rien faire */ else { echo "Erreur"; } break; // fin cas modifier /* Action = supprimer, on supprime une news */ case "supprimer": /* Si l'i existe, on fait une simple requète pour supprimer la news */ if(isset($_GET['id'])) { $id = intval(htmlentities($_GET['id'])); $sql ='DELETE FROM news WHERE id='.$id.''; $req= mysql_query($sql) or die(mysql_error()); echo '<a href="admin.php">Cliquez ici</a>'; } /* Pas d'id ? Probleme */ else { echo "erreur"; } break; } } /* Dans le cas ou il n'y a pas d'action posté dans l'url, on affiche nos choix via une liste */ else { ?> <ul> <li><a href="admin.php?action=creer">Créer une news</a></li> <li><a href="admin.php?action=gerer">Gérer</a></li> </ul> <? } ?> |
4.Pour terminer, le code du fichier qui génère le flux RSS. Je me suis cantonné au minimum, mais en faisant quelques recherches vous verrez que vous pourrez ajouter des informations supplémentaires facilement (en ajoutant un élément dans la boucle en fait).
<?php /* Connexion à la BDD */ require "config.php"; mysql_connect($adresse, $nom, $motdepasse); mysql_select_db($database); mysql_query("SETNAMES 'utf8'"); /* On est olbigé d'écire ça avec un "echo" a cause du "<? et ?>" qui ressemble au php */ echo '<?xml version="1.0" encoding="iso-8859-1"?>'; /* Liste des dernières 10 news */ $sql = 'SELECT * FROM news LIMIT 0,9'; $req = mysql_query($sql) or die(mysql_error()); ?> <rss version="2.0"> <channel> <title>Tutoriels-video</title> <description>Flux tuto video</description> <link>http://www.tutoriels-video.fr</link> <?php /* On boucle le motif qui se répètera */ while ($data = mysql_fetch_assoc($req)) { ?> <item> <title><?php echo stripslashes($data['titre']);?></title> <!-- On utilise "<![CDATA[ truc à afficher ]]>" car il y a du code html, c'est pour éviter les bugs --> <description><![CDATA[<?php echo stripslashes($data['description']);?>]]></description> <pubDate> <?php echo ''.date("D, d M Y G:i:s", strtotime($data['date'])).' GMT'; ?> </pubDate> <link>http://127.0.0.1/tutoriel/news/index.php?id=<?php echo $data['id'];?></link> </item> <?php } ?> </channel> </rss> |
Étant donné que ces codes sont long, je vous ai fait un petit fichier .zip (ou .tar.gz pour ceux qui veulent ce format) avec tous les fichiers du tutoriel. J’ai même, améliorer (légèrement) la mise en page.
![]()
Télécharger l’archive en .zip
Télécharger l’archive en .tar.gz (linux)
Le tutoriel est enfin terminé, j’espère que cela vous aura plu, si vous avez des questions laissez des commentaires ou faites un tour sur le forum qui est plus adapté pour poster du code !
-
-
-
-
-
Salut!
Je n’ai pas encore regardé la vidéo, mais au vu du screen j’ai déjà un retour à te faire : plutôt que d’utiliser addslashes() pour protéger tes données, je te conseillerai plutôt la fonction mysql_real_escape_string(), qui est vraiment faîte pour ça. Ou mieux : utilise PDO.
Salut !
Merci de la remarque, c’est toujours une vieille habitude que j’ai
.
Mais j’ai utilisé addslashes parce que j’avais peur que mysql_real_escape_string me fasse sauter la mise en forme de tinymce. Néanmoins, si ça marche avec cette 2eme fonction, autant l’utiliser !
Pour PDO, j’en ai entendu parlé, mais je ne sais strictement rien dessus, ca sera ma prochaine étape dans mon apprentissage du PHP (avec la POO aussi).
Je viens de découvrir ton site, il est vraiment très bien.
Merci pour tes tuto.
Je c’est pas si tu connait ce site avec de bon tuto aussi.
http://www.grafikart.fr/tutoriels
Pour PDO je crois qu’il y à un tuto sur Le Site Du Zéro.
A bientôt.
Merci
Grafikart, je connais. D’ailleurs il est dans ma liste de lien à droite du blog. C’est grâce à lui si le site existe, il m’a donnée l’idée.
Ok, j’avais pas vu^^
Moi aussi j’ai dans l’idée de faire des Tuto vidéo, mais je ne c’est pas encore sur quoi.
Bonne journée a toi. A+
Super ton tuto. Je les vue en entier, je le regarde de nouveau demain et je m’attaque au code. J’ai tout pigé, plus ou moins les memes base que l’AS3 (en gros).
Par contre, la ou je vais avoir du mal, c’est pour faire une mise en page (CSS) répétable a chaque news.
As tu une solutions ? est ce long ? (je connais le CSS, mais de la à l’intégré dans ton code, fiouf).
Merci d’avance
Bonjour,
C’est vrai que j’aurais peut être du parler un peu plus du CSS mais le tuto aurait duré 2 heures …
Pour moi, le CSS c’est le plus simple. Ce que je fais, c’est que je place des div avec des class dans la boucle qui liste les news. Ensuite suffit de lui donner une mise en forme (rien que de mettre une bordure, un background, des marges, c’est pas mal).
Ensuite je met aussi des balises paragraphes ou des titres (h1 etc…) avec une class particulière (toujours dans la boucle qui liste les news). Après, c’est quasiment fini, il suffit de mettre les effets en CSS en utilisant les diverses propriétés qui existe.
En revanche, je vous conseille fortement de mettre ça dans un fichier CSS à part, et pas comme moi dans le tutoriel ou je met ça directement dans le code php (ce n’est pas propre du tout, c’est pour gagner du temps). Ne mettez pas d’id non plus, utilisé des class car les « motifs » se répètent dans la boucle (en gros « id » = utilisable une seul fois).
Ce n’est pas très compliqué en prenant son temps. Ce n’est pas pour autant que c’est long, je pense qu’en 30-40 minutes on arrive à un résultat correcte (après personnellement je fais des sites plutôt sobre et extensible, donc c’est rapide).
Bonne chance
Bonsoir bon j’en suis a 18 minute de tuto
petites erreurs →
Pourquoi proteger ton GET id avec intval puis avec htmlentities
Htmlentities convertis tout ce qui es possible en son entité html ça marcherai avec un > ou un < mais un nombre y a pas d'interet ?
intval c'est trés bien et suffisant
Ensuite niveau traitement en lieu et place de $titre = addslashes(htmlentities
$titre = htmlspecialchars(stripcslashes(trim($_POST["titre"]))); je pense que c'est mieux
et aprés t'as requete tu la protege aussi car toi tu la balance comme ça donc le mieux
$result = mysql_query("INSERT INTO CONTENU VALUES
(
'',
'".mysql_real_escape_string($titre)."',
'".mysql_real_escape_string($description)."',
Ne pas tenir compte de çà je me suis basé sur le screen
Ensuite niveau traitement en lieu et place de $titre = addslashes(htmlentities
$titre = htmlspecialchars(stripcslashes(trim($_POST["titre"]))); je pense que c’est mieux
Salut,
Merci beaucoup pour toutes ces remarques constructive.
C’est juste, que niveau sécurité je fais très attention et par conséquent je préfère mettre plus de chose qu’il n’en faut, par exemple le htmlentities avec le intval. Je m’en doutais que c’était inutile, mais dans le doute j’ai préféré faire comme ça.
Ensuite ma requête, je ne l’ai pas protégé car j’ai justement utiliser toute les fonctions avant, donc normalement il n’y à pas de problème (j’aurais du utiliser un « mysql_real_escape_string » à la place « addslashes » quand même).
En tout cas merci pour toutes ces remarques. Je fais changer ma façon de faire à l’avenir et adopter tes méthodes qui ont l’air plus correcte !
En plus, pour les requêtes SQL, je suis en train d’apprendre PDO, donc ça devrait être un peu plus sécurisé (avec les requêtes préparé si j’ai bien compris le truc).
Encore merci
Y a pas de soucis l’erreur est humaine je suis loin d’etre un pros et j’aime bien tout ce que tu partage , je me suis permis cette remarque car on me l’as fait ici. Idem j’essaie de mettre a PDO et a la POO :s
on me la fait aussi et pas ici pardon pour le double poste
Salut, tuto très intéressant comme d’hab :p
(Tu n’imagines pas à quel point c’est frustrant quand tu cherches l’une de tes erreurs et qu’on la trouve avant toi, je me retrouve comme un con devant mon écran « Là le ; en fin de ligneeeuh !! », cela dit, je dit ça en plaisantant mais je trouve utile que tu laisses tes erreurs pour aider les débutants à les chercher eux même sur leur code)
Au passage, sur le flux RSS:
Tu peux directement intégrer un texte dans la sortie avec des antislash:
Continu c’est vraiment nickel :p
plush plush.
Désolé pour le double post la balise code ne semble pas avoir marcher le coup d’avant.
Au passage, sur le flux RSS:
echo ».date(« D, d M Y G:i:s », strtotime($data['date'])).’ GMT’;
Tu peux directement intégrer un texte dans la sortie avec des antislash:
echo date(« D, d M Y G:i:s \G\M\T », strtotime($data['date']));
Super ce tutoriel, un peu long certes mais très complet. Je viens de le regarder entièrement, j’y jetterai un coup d’œil à tête reposé.
Manque plus qu’un petit système de commentaire, mais j’ose espérer en trouver un ici!
Bonne chance pour la suite!
Gloubi.
Merci beaucoup pour ce tuto, j’en cherchais un qui comprenais tout ça ! Plus qu’à l’adapter à mes besoins.
Bonjour, je te remercie pour ce tuto mais je me permet d’y ajouter un petit commentaire par rapport à la récup&ération des 5 news… il est préférable de faire :
$sql = ‘SELECT * FROM news ORDER BY date DESC LIMIT 0,5′;
$req = mysqli_query($dbc, $sql) or die(mysql_error());
Cordialement
Merci pour la précision, c’est vrai que je suis resté « old school », mais dans mes prochains tutoriels j’utiliserais surement PDO qui est encore plus sécurisé et à la mode en ce moment
.