Magazine Internet

PHP : Un cache pour nos fichiers stockés dans MySQL

Publié le 22 novembre 2009 par Methylbro

Au niveau de MySQL

Bien évidemment un serveur de base de données n’a pas été conçu pour stocker massivement des fichiers. Il n’a pas pour vocation de manipuler exclusivement ce type d’informations. Votre système de fichier sera bien évidemment beaucoup plus performant pour effectuer cette tâche.

Stocker des fichiers dans vos tables alourdira considérablement la taille de ces dernières. Le serveur de données aura donc besoin de plus de temps et de ressources pour les parcourir lors de vos requêtes, ce qui peut nuire grandement au temps d’exécution global de vos script.

A contrario centraliser les données est toujours quelque chose de très intéressant pour la maintenance d’une application. Les backups sont plus faciles à gérer lorsque les données nécessaires pour un programme sont réunies au même endroit. Comme cela peut être le cas avec une base de données.

Le débit de données entre le serveur et votre script

Il y a un point primordial que nous devront prendre en compte si nous souhaitons tout de même utiliser MySQL pour stocker nos fichiers : c’est le débit d’information qui va circuler entre le serveur de base de données et notre script.

En effet outre les problèmes directement liés à notre SGBDR a chaque fois que nous allons vouloir faire appel à l’un de nos fichiers stocké en base celui-ci va devoir parcourir un long chemin pour arriver jusqu'à nous.

Pour illustrer mon propos ; jetez un coups d’œil sur le schéma suivant :

Le débit de données entre le serveur et votre script

La solution que l’on peut facilement envisager c’est de créer un cache au sein de notre application qui stockera dans le système de fichiers nos fichiers tant qu’ils seront valables par rapport à leurs version dans la base de données.

La méthode FileFromDB::headers()

A partir de ce que nous avons fait jusqu'à présent, mettre en place ce petit cache va s’avérer très facile. Commençons par modifier notre classe FileFromDB qui, je vous le rappelle, nous permet de manipuler nos fichiers stockés dans la base de données.

Même si nous ne souhaitons pas faire circuler nos fichiers inutilement entre notre script et la base de données nous auront besoin néanmoins d’un grand nombre d’informations les concernant. Principalement leur nom ainsi que la date de leur dernière modification.

public function headers() {
global $PDO;
$stmt = $PDO->prepare("SELECT name, type, UNIX_TIMESTAMP(updated_date) AS updated_date FROM FILE WHERE name = ?");
$stmt->bindParam(1, $this->filename);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_OBJ);
}

C’est le rôle de cette nouvelle méthode. Elle nous donnera uniquement ces informations sous la forme d’un objet de type sdtClass. Ce qui évitera d’avoir à aller chercher notre fichier inutilement à chaque demandes.

Une nouvelle page de download

Maintenant que nous disposons des outils nécessaires, nous pouvons modifier notre page de téléchargement de fichiers en y ajoutant notre petit système de cache. Par défaut donc, notre script enverra donc au visiteur le fichier contenu dans le cache.

Ce dernier sera néanmoins renouvelé par le fichier contenu dans la base de donnée si l’une de ces trois conditions n’est pas rempli :

  1. Le fichier n’existe pas encore dans le cache
  2. Le fichier stocké dans le cache à dépasser son temps de vie maximum
  3. Le fichier stocké dans le cache n’est plus à jour avec celui stocké dans la base de données
$cache_path = 'cache/';
$cache_lifetime = 3600;
if (isset($_GET['filename'])) {
$File = new FileFromDB($_GET['filename']);
$FileHeaders = $File->headers();
$file_cache = $cache_path.$FileHeaders->name;
if (!file_exists($file_cache)
|| filemtime($file_cache)+$cache_lifetime
|| filemtime($file_cache)<=$FileHeaders->updated_date) {
$File->output($file_cache);
}
header("Content-Type: {$FileHeaders->type}");
header("Content-Disposition: inline; filename={$FileHeaders->name}");
header("Last-Modified: ".date('r', $FileHeaders->updated_date));
readfile($file_cache);
}

Dans un prochain billet je reviendrais sur tout ce que nous avons vu sur le stockage de fichier au sein d’une base de données avant de conclure cet article. Je vous proposerais également les sources utilisées dans nos exemples commentés.


Retour à La Une de Logo Paperblog

A propos de l’auteur


Methylbro 17 partages Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte

Dossier Paperblog