Création d'un site web full cache avec le mkFramework

Une conception très performante

Michael Bertocchi

Commentez

- Titre : Création d'un site web full cache avec le mkFramework

- Auteur : Michael Bertocchi

- Parution : 19 mai 2014

- Mise à jour : 8 février 2020

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2014 Michael Bertocchi. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Voir également :

- Présentation du framework

- Créer son site de microblogging

Sommaire

- I. Introduction

- II. L'architecture cible

- III. La base de données

- IV. Création des arborescences des deux sites

- IV-A. Site public

- IV-B. Site d'administration (ou backoffice)

- V. Profil de connexion

- VI. Création de la couche modèle

- VII. Génération des CRUD « article » et « catégorie »

- VIII. Création de la partie authentification

- IX. Création de la partie publique

- X. URL rewriting

- XI. Génération du cache

- XII. Appel de la génération du cache

- XIII. Conclusion

- XIV. Remerciements

I - Introduction

Dans le cas de beaucoup de sites, on passe plus de temps à consulter le contenu qu'à le modifier, par exemple pour un blog, journal, site institutionnel…

Dans ces cas-là, on requête sans cesse la base de données pour récupérer les mêmes données.

On peut toujours envisager une gestion de cache « normal » : en cachant les vues, mais ce système nécessite de faire des accès I/O pour vérifier la validité de ces fichiers de cache.

Dans ce tutoriel, nous allons créer un site avec un mécanisme de création de cache « total » en utilisant le mkframework.

Pour information, créer un cache revient à enregistrer le code HTML généré pour éviter lors de l'appel du prochain internaute de refaire le même traitement (requête en base de données, boucle PHP…)

Ce système de génération de cache permettra :

- de soulager la base de données, elle ne sera sollicitée qu'à la modification du contenu ;

- d'obtenir des performances excellentes, en effet aucun calcul, requête… ne seront utilisés, le serveur ne fera que retourner le code HTML ;

- sécurité totale : aucune faille XSS*, SQL injection**… l'internaute n'évoluant que sur des pages HTML.

Pour la sécurité :

Il est à préciser que c'est le site public, constitué uniquement de pages HTML qui sera totalement exempt de faille de sécurité XSS, SQL injection…

Le site d'administration, lui, sera tout comme n'importe quel site PHP potentiellement sujet à des failles SQL ou XSS. Je vous invite donc, soit à le laisser sur votre ordinateur et copier le site « public » généré sur le serveur, soit appliquer un filtre IP sur le virtualhost du site d'administration afin de ne permettre l'accès qu'à votre ordinateur pour générer le cache.

* XSS : faille permettant d'injecter du code dans une page web en profitant d'une variable de contexte non protégée, plus d'information sur Developpez, https://julien-pauli.developpez.com/tutoriels/securite/developpement-web-securite/?page=xss.

**SQL injection : faille permettant de modifier la requête SQL initiale, plus d'information sur Developpez, https://julien-pauli.developpez.com/tutoriels/securite/developpement-web-securite/?page=injections-sql.

II - L'architecture cible

Le site sera divisé en deux sites totalement distincts :

- un site d'administration du contenu, qui générera le cache ;

- le site public qui sera accessible pour les internautes et les robots d'indexation.

Vous pouvez mettre ces deux sites sur deux serveurs différents, deux URL différentes ou même choisir de mettre la partie administration uniquement sur votre ordinateur et de copier le cache généré sur votre serveur web « public ».

III - La base de données

Pour ce tutoriel, on utilisera une base de données MySQL (ou MariaDb).

Créons une base de données « monBlogDb ».

Pour cela, exécutez le code SQL suivant :

CREATE TABLE `article` (
`id` int(11) NOT NULL auto_increment,
`titre` varchar(50) NOT NULL,
`resume` text NOT NULL,
`auteur_id` int(11) NOT NULL,
`categorie_id` int(11) NOT NULL,
PRIMARY KEY  (`id`)
);

CREATE TABLE `categorie` (
`id` int(11) NOT NULL auto_increment,
`label` varchar(30) NOT NULL,
PRIMARY KEY  (`id`)
);

CREATE TABLE `auteur` (
`id` int(11) NOT NULL auto_increment,
`nom` varchar(30) NOT NULL,
`prenom` varchar(30) NOT NULL,
`login` varchar(30) NOT NULL,
`password` varchar(50) NOT NULL,
PRIMARY KEY  (`id`)
);

IV - Création des arborescences des deux sites

Nous allons ici créer les deux sites. Le premier, le site public, hébergera ce site « généré » en HTML. Le second, le site d'administration, hébergera l'application PHP utilisant le framework.

IV-A - Site public

Créez le répertoire monSitePublic dans l'arborescence de votre serveur Apache, par exemple /var/www sur un serveur GNU/Linux :

/var/www/monSitePublic

IV-B - Site d'administration (ou backoffice)

Après avoir téléchargé le framework (sur http://mkframework.com), on décompresse l'archive dans le répertoire web de notre serveur apache : /var/www/mkframework/

Rendez-vous ensuite à l'adresse http://localhost/mkframework :

Votre navigateur affiche le builder, saisissez le nom de l'application monApplication et validez.

Le générateur va créer l'arborescence de votre application dans le répertoire data/genere du framework.

Il est désormais présent dans /var/www/framework/data/genere/monApplication.

Il sera déplacé une fois que l'on aura plus besoin du builder.

V - Profil de connexion

L'application générée contient des fichiers de configuration dans son répertoire conf/ dont un fichier de connexion. Éditez le fichier de connexion conf/connexion.ini.php et renseignez le profil suivant :

monBlog.dsn="mysql:dbname=monBlogDb;host=localhost"
monBlog.sgbd=pdo_mysql
monBlog.username=root
monBlog.password=root

VI - Création de la couche modèle

Le mkFramework, comme beaucoup d'autres frameworks utilise le schéma MVC (Modèle-Vue-Contrôleur).

Il faut donc créer des classes modèles pour interagir avec notre base de données.

Dans le builder, cliquez sur « créer la couche modèle » :

On souhaiterait que cette application permette de renseigner facilement la catégorie.

Pour cela, on demande au builder de créer une méthode qui retournera un tableau indexé.

Pour la table « categorie », cochez la case « Retourne un tableau avec » et sélectionnez comme valeur « label ».

Faites de même pour la table « auteur ».

VII - Génération des CRUD « article » et « catégorie »

CRUD signifie Create, Read, Update et Delete, ce terme désigne les actions nécessaires pour administrer une table. Généralement, cela consiste en un tableau listant les enregistrements plus des pages pour ajouter, modifier, afficher et supprimer ceux-ci.

Pour permettre d'administrer notre site, nous allons créer des modules d'édition de contenu pour nos articles et catégories.

Pour cela, on va utiliser le builder.

Cliquez sur « créer un module CRUD ».

Sélectionnez votre classe modèle « article ».

Indiquez pour le champ categorie_id d'utiliser la méthode geSelect() générée précédemment dans la couche modèle.

Décochez la case auteur_id, car nous forcerons l'identifiant de l'auteur (par celui connecté).

Validez avec le bouton « créer ».

Créez de même le module « adminCategorie ».

À la fin, validez le formulaire.

VIII - Création de la partie authentification

Notre partie administration du site devrait être accessible uniquement par les utilisateurs authentifiés.

Dans le builder, cliquez sur « Créer un module d'authentification avec inscription ».

Le builder vous affiche une erreur : il ne voit pas de classe modèle « utilisable ».

Il vous demande d'ajouter ces deux méthodes à la classe qui gère la table contenant les comptes de connexion (dans notre cas à la classe auteur).

Éditez votre fichier de classe modèle model_auteur.php et copiez-collez ces deux méthodes dans la classe model_auteur.

Attention : pour la méthode getListAccount, modifiez $oAccount->pass par $oAccount->password (notre champ de mot de passe s'appelle password et non pass).

Puis retournez dans le builder et recliquez sur « Créer un module d'authentification avec inscription ».

Le builder vous permet ici de choisir la classe modèle à utiliser pour l'authentification (model_auteur précédemment modifiée).

- Le nom du module à créer, ici « auth ».

- Le module à rediriger une fois authentifié.

- Le champ de login et celui de mot de passe.

Cliquez sur « Générer le module d'authentification ».

Vous voyez ici que l'on vous demande d'éditer un fichier de configuration afin d'activer l'authentification et d'indiquer le nom du module le gérant.

Vous pouvez simplement cliquer sur le lien conf/site.ini.php

et modifier la valeur de enabled dans la section [auth].

Ceci active l'authentification sur l'ensemble du site. Pour vous y connecter, il vous faut créer un compte.

Connectez-vous sur votre site, en cliquant sur « voir le site » :

Vous voyez un formulaire d'authentification avec un lien pour s'inscrire :

Cliquez sur « S'inscrire ».

Créez un compte puis loguez-vous.

Vous arrivez sur la page de CRUD des livres, mais c'est un peu trop pauvre, on va ajouter un menu pour naviguer :

Le builder vous liste les modules qu'il trouve dans votre application.

Vous avez la possibilité de créer des liens facilement à partir de ceux-ci.

Nous allons ici créer trois liens : un pour accéder aux articles, un autre aux catégories et enfin le dernier pour se déconnecter.

Cliquez sur « Générer le menu ».

Une fois le module généré, le builder vous indique comment l'ajouter dans votre application.

Il faut éditer les modules « categories » et « articles » pour utiliser ce module, éditez le fichier module/articles/main.php et ajoutez à la fin de votre méthode before(), la ligne :

$this->oLayout->addModule('menu','menu::index');

Faites de même pour le module « categories ».

IX - Création de la partie publique

Nous allons utiliser le builder pour générer un module de listage des articles.

Cliquez sur « Créer un module en lecture seule ».

Validez le formulaire.

X - URL rewriting

Avant de générer notre cache, il faudrait définir des règles d'URL rewriting utilisant des adresses plus propres qui seront utilisées pour créer les pages HTML.

Éditez votre fichier conf/site.ini.php et indiquez dans la section urlrewriting :

[urlrewriting]
enabled=1

Ensuite, éditez le fichier des routes (conf/routing.php) pour ajouter deux routes :

<?php
$tab=array(
'index.html' => array(
'nav'=>'publicArticle::list',
),
'article_:id:.html' =>  array(
'nav'=>'publicArticle::show',
'tParam' => array('id')
),
'404' => array('nav'=>'publicArticle'),
);

L'une utilise index.html pour appeler la méthode _list() du module module_publicArticle.

L'autre utilise article_ suivi de l'id de l'article à afficher via la méthode _show() du même module.

Plus d'informations sur l'URL rewriting ici : http://mkframework.com/faq.html#urlrewriting

XI - Génération du cache

Vous avez deux méthodes dans publicArticle : _list() et _show().

Vous pouvez dupliquer votre méthode _list pour faire une méthode qui générera le cache :

public function generateCacheList(){

//on appelle la méthode before(),
//comme le ferait le framework
//pour créer le layout, charger les éventuels menus...
$this->before();
//on appelle l'action à mettre en cache:
$this->_list();

//c'est ici que cela diffère: on récupère la sortie
$sContent=$this->oLayout->getOutput();

//on demande au framework de générer le même lien que celui utilisé dans la vue
$sUrl=_root::getLink('publicArticle::list');

//on l'enregistre dans le répertoire de notre site public
$oFile=new _file('/var/www/monSitePublic/'.$sUrl);
$oFile->setContent($sContent);
$oFile->save();
}

Idem pour la page d'affichage d'un article :

public function generateCacheShow($id){

//on appelle la méthode before(),
//comme le ferait le framework
//pour créer le layout, charger les éventuels menus...
$this->before();
//on force le paramètre d'id pour afficher le bon article
_root::setParam('id',$id);
//on appelle l'action à mettre en cache:
$this->_show();

//c'est ici que cela diffère: on récupère la sortie
$sContent=$oLayout->getOutput();

//on demande au framework de générer le même lien que celui utilisé dans la vue
$sUrl=_root::getLink('publicArticle::show',array('id'=>$id));

//on l'enregistre dans le répertoire de notre site public
$oFile=new _file('/var/www/monSitePublic/'.$sUrl);
$oFile->setContent($sContent);
$oFile->save();
}

XII - Appel de la génération du cache

Dans votre module d'administration des articles adminArticle, éditez le fichier main.php et ajoutez dans la méthode processSave() :

//on instancie le module public
$oModuleArticlePublic= new module_publicArticle;
//on appelle la méthode de génération du cache de liste d'articles
$oModuleArticlePublic->generateCacheList();

//puis pour l'article ajouté/modifié
$id=$oArticle->id;
//on récupère son id et l'on demande au module public
//de générer le cache de sa page d'affichage
$oModuleArticlePublic->generateCacheShow($id);

À chaque fois que vous ajoutez ou modifiez un article, les pages HTML sont générées dans votre répertoire public.

Pensez bien à ajouter vos fichiers CSS et images de mise en page dans l'arborescence publique /var/www/monSitePublic

Une dernière chose : si vous souhaitez sécuriser au maximum votre partie administration, vous pouvez, soit la garder uniquement sur votre ordinateur et copier le cache du site sur votre serveur web public, soit mettre votre site web sur une autre URL et limiter les adresses IP autorisées à y accéder (soit via htaccess, soit via un virtualhost).

XIII - Conclusion

Vous avez pu voir dans ce tutoriel comment créer un site « full cache », vous avez ici une bonne base pour créer une version de votre site avec le même procédé.

Note : ce procédé n'est pas exclusif au mkframework, mais ce framework permet de le mettre en place simplement via sa gestion particulière du cache.

XIV - Remerciements

Je souhaiterais remercier f-leb qui m'a bien soutenu sur ce tutoriel ainsi que chrtophe pour sa relecture technique.