Bonjour

Dans un site WEB (docker PHP), je gère un fichier de personnes avec des données stockées sur un serveur SQL. J'ai mis en place un système de trombinoscope où chacun dépose sa photo. L'accès est soumis à identification et seuls les admin peuvent consulter l'ensemble des fiches individuelles. Et je souhaite stocker les photos en dehors du répertoire WEB, par souci de sécurité. Le nom de la photo est stocké dans la base SQL.
Dans une page trombinoscope.php j'affiche la fiche individuelle avec la photo (ou bien côté admin, une table avec l'ensemble des photos).

L'arborescence d'exemple :
web
--test
----www
------data (dossier hors WEB contenant les photos)
--------photo01.jpg
--------photo02.jpg
...
------public (c'est le répertoire WEB par défaut)
--------index.php
--------trombinoscope.php

Dans la page WEB en PHP, je fais une requête SQL pour récupérer le nom de la photo :
$nom_photo=$row['photo'];

Le chemin d'accès physique au dossier des photos est stocké dans la variable $chemin :
$chemin="/web/test/www/data/";
Et, c'est là que je coince, pour générer le SRC de la balise IMG. Je n'arrive pas à savoir si c'est seulement possible.

<img src="<?= $photo ?>" />
Quoi mettre dans $photo ?
$photo=$chemin . $nom_photo; // chemin physique, ça ne fonctionne pas
$photo= "../data/" . $nom_photo; // chemin relatif, mais non sens puisque en dehors du dossier web par défaut

Apparemment SRC a besoin d'un chemin virtuel. Or, le dossier DATA se trouve en dehors du WEB...
Merci pour votre aide qui sera la bienvenue.

Pascal

4 réponses


Bonjour Pascal,

Si les photos sont dans un répertoire protégé (par Htaccess par exemple) ou dans un répertoire non accessible via le chemin HTTP (je suppose que c'est ce que l'on sous-entend par "dossier hors WEB"), alors ça ne peut pas fonctionner.

Pour afficher des photos protégées et les afficher uniquement si l'utilisateur a le droit de les voir, 2 possiblités à ma connaissance :

  • stocker les images au format "base64" dans la base de données (ça prend de la place...);
  • générer l'image "à la volée" via PHP à partir du fichier d'origine, puisque PHP peut accéder au répertoire protégé (ça coute de la ressource);

Peut être que d'autres personnes auront d'autres idées...

Merci Soundboy39 pour cette réponse.
J'ai creusé un peu et essayé une solution qui a le mérite de fonctionner.

Dans la page où j'affiche les images, j'appelle un script PHP dans le SRC de la balise IMG, en passant dans le GET le nom du fichier photo (nom stocké dans la base SQL) :
<img src="decode_image.php?image=<?= $row['nom_photo'] ?>" />

Le script decode_image.php :
<?php
$chemin_photos="/web/www/photos/"; // dossier hors WEB
$image=$_GET['image']; // on récupère le nom de l'image

// ici on récupère l'extension de l'image pour générer le header qui va bien
$file_extension = strtolower(substr(strrchr($image,"."),1));
switch( $file_extension ) {
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpg": $ctype="image/jpeg"; break;
case "svg": $ctype="image/svg+xml"; break;
default:
}

header('Content-type: ' . $ctype);
readfile($chemin_photos . $image);
?>

C'était donc possible ;-)

Et c'était le second point indiqué par Soundboy39 ^^

Sinon la solution que propose laravel et qui fonctionne bien. Avoir un lien symbolique vers le dossier.

Merci mais je n'utilise pas Laravel.
Et, oui, le script que j'indique correspond à la création d'image "à la volée". Si ça peut aider c'est toujours intéressant je trouve d'avoir un script explicite.
J'irai voir les tutos de Jonathan sur Laravel 😉