Devblog développement web, WordPress & WooCommerce

[beta] Une « cache-machine » pour WordPress

[

Les fichiers (à jour) sont disponibles ici : https://github.com/mbcreation/CacheMachine

Je teste depuis quelques jours un petit script php de ma composition permettant de mettre l’intégralité d’un site WordPress en cache. Je vous le présente aujourd’hui avec l’espoir d’avoir quelques retours et commentaires puisque celui me paraît prometteur mais très probablement imparfait !

Constat : La plupart des sites WordPress que je développe pour moi ou pour mes client n’utilisent que très peu les fonctionnalités « sociales » de WordPress (compte utilisateur notamment) et sont assez rarement mis à jour. La notion de site « dynamique » a finalement assez peu de sens sur la plupart de requêtes. Hors pendant ce temps-là, Google met la pression sur les temps de chargement et WordPress devient de plus en plus gourmand.

Solution envisagée : intercepter toutes les requêtes de type « GET » des utilisateurs non-connectés pour leur proposer une version html intégrale de la page demandée. Le tout en court-circuitant totalement WordPress pour réduire au minimum les calculs et donc le temps de chargement.

Contraintes : ne pas toucher au coeur de WordPress (évidemment…)

Approche technique :

1 – Modifier le fichier .htaccess de base pour intercepter tout le trafic entrant, puis servir en fonction du contexte soit un fichier statique, soit la réponse par défaut (l’index de WordPress).

2 – Développer un script de mise en cache de la page demandées sous certaines conditions seulement (pour l’instant, exclusion des requêtes POST – commentaires, formulaire – celles des visiteurs connectés, celles contenant des variable GET – recherche par exemple – et celles émises par le serveur lui-même pour éviter que le script boucle sur lui-même…

3 – Ajout d’une action sur le hook « save_post » afin de supprimer la version cachée d’un article. Ajout d’une action sur le hook « preprocess_comment » pour mettre à jour un article à l’envoi d’un commentaire.

Todo :

Vérifié la bonne gestion des 404
Se prémunir d’une indexation éventuelle de tout le cache !
Améliorer les mécanismes de remplacement du cache (actions, filtres…)
…vos retours/commentaires ?

En terme d’organisation « fichiers », le script php sera nommé cache.php et mis à la racine de votre site. Il conviendra également de créer un dossier « cache » à la racine du site et accessible en écriture par le serveur.

A noter qu’il est tout à fait possible voire souhaitable d’ajouter une durée de vie sur les fichiers mis en cache (en ajoutant par exemple un test avec filemtime).

Le script doit impérativement être utilisé avec un WordPress utilisant des permaliens de type « postname » sur un hébergement autorisant file_get_contents().

Le .htaccess modifié :

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^cache.php$ - [L]
RewriteRule ^$ /cache.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /cache.php [L]
</IfModule>
# END WordPress

Le fichier cache.php (à mettre à la racine du site)

<?php


if($_SERVER['REMOTE_ADDR'] != 'IP SERVEUR' && $_SERVER['REQUEST_METHOD'] == 'GET' && empty($_GET) && null === $cookie = $_COOKIE['wordpress_logged_in_'.md5('http://'.$_SERVER['HTTP_HOST'])]){


	$cachefolder = "cache";
	
	$flaturl = end(explode('/',rtrim($_SERVER['REQUEST_URI'],'/')));
	
	if($flaturl == '') $flaturl = 'home';

		if(!file_exists($cachefolder.'/'.$flaturl)){
          
		$data = file_get_contents('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
		$response = $http_response_header[0];
		if(strpos($response, '200')!==false){
			
			file_put_contents($cachefolder.'/'.$flaturl, $data);
		}
		else{
			
			include('index.php');
			exit;

		}


	}
	
	readfile($cachefolder.'/'.$flaturl);
	exit;

}

else{
	
	include('index.php');
	exit;

}

?>

Deux filtres que vous pouvez ajouter à votre functions.php (dans votre thème). Ce ne sont que des exemples…

// supprimer le cache article et le cache home à la soumission d'un commentaire
function cache_comment_erase($incomingcomment){
 
 $post = get_post($incomingcomment['comment_post_id']);
 unlink(ABSPATH.'/cache/'.$post->post_name);
 unlink(ABSPATH.'/cache/home');
 return $incomingcomment;

}

add_action( 'preprocess_comment', 'cache_comment_erase');

// supprimer le cache article et le cache home à la modification d'un article/page
function cache_erase($post_ID, $post) {
		unlink(ABSPATH.'/cache/'.$post->post_name);
		unlink(ABSPATH.'/cache/home');
}

add_action('save_post', 'cache_erase', 10, 2);

Devblog développement web, WordPress & WooCommerce

Articles récents

Catégories