Magazine Internet

PHP : Lire un fichier stocké dans la base de données

Publié le 20 novembre 2009 par Methylbro

La méthode FileFromDB ::output()

Dans notre dernier chapitre sur ce sujet, nous avons commencé l’élaboration d’une classe FileFromDB nous permettant de manipuler des fichiers stockés dans une base de données.

Nous allons poursuivre la conception de cette dernière en lui rajoutant une méthode output() qui nous permettra de lire un fichier vers le flux standard de sortie ou d’enregistrer celui-ci dans le système de fichiers.

Cette méthode acceptera donc un paramètre facultatif $filename. Si celui-ci est fournis nous enregistrerons une copie du fichier stocké dans la base de données vers la destination indiqué au sein du système de fichiers.

Sinon nous afficherons le fichier directement vers le flux standard de sortie. Comme il s’agit d’Apache dans notre exemple, nous prendrons soin d’indiquer certains en-têtes HTTP nécessaire pour que le client comprenne de quel fichier il s’agit.

public function output($filename=null) {
global $PDO;
$stmt = $PDO->prepare("SELECT type, UNIX_TIMESTAMP(updated_date), data FROM FILE WHERE name = ?");
$stmt->bindParam(1, $this->filename);
$stmt->execute();
$stmt->bindColumn(1, $type, PDO::PARAM_STR, 256);
$stmt->bindColumn(2, $updated_date, PDO::PARAM_INT);
$stmt->bindColumn(3, $data, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);
if (is_null($filename)) {
header("Content-Type: $type");
header("Content-Disposition: inline; filename={$this->filename}");
header("Last-Modified: ".date('r', $updated_date));
//return fpassthru($data);
return print($data);
} else {
$hdle = fopen($filename, 'wb');
//return stream_copy_to_stream($data, $hdle);
return fwrite($hdle, $data);
}
}

Le bug #40913 de PHP

e bug #40913 de PHP

Comme vous pourrez le voir j’ai laissé deux lignes en commentaires dans la méthode ci-dessus. En effet a ce stade nous ne pourrons malheureusement pas utiliser d’objet large binaire (Binary Large Object) car PHP et PDO sont encore victimes d’un bug non corrigé à ce sujet.

Le problème vient du fait que, malgré que l’on indique à PDO que l’on souhaite recevoir un paramètre de type PDO::PARAM_LOB (Objet Binaire Large) celui-ci nous retourne une chaîne de caractère (PDO::PARAM_STR). Il deviens impossible alors de traiter notre valeur comme une ressource de flux (utilisable notamment avec les fonctions fpassthru() et stream_copy_to_stream().

En attendant que ce problème soit corrigé j’utiliserais donc print() et fwrite() dans mon exemple. Mais attention, cette méthode de remplacement consomme énormément plus en ressource qu’un simple traitement par flux. Ne l’utilisez donc pas en production (surtout sur des sites avec une grosse charge).

La page de download

Maintenant que nous avons une solution nous permettant de récupérer des fichiers stockés dans notre base de données MySQL, nous pouvons facilement créer un petit script pour télécharger ces fichiers.

if (isset($_GET['filename'])) {
$File = new FileFromDB($_GET['filename']);
$File->output();
}

Encore une fois ce script restera simple et l’on omettra toutes les vérifications d’usage en termes de sécurité. Ce n’est pas le sujet abordé.

Dans un prochain article nous verrons que notre solution demande énormément de ressources inutiles. Nous réglerons donc ces problèmes en implémentant un petit système de cache applicatif côté PHP.


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