Generally what you want to do is:
Determine in what sort of way you can uniquely identify an image - in a way that doesn't leak information. A primary key so to speak.
If the metadata for your images happens to be stored in a database, then each image likely already has a unique key (the primary key in that table; perhaps an auto_incrementing integer). It could be a string as well (or a UUID); it just has to be something you'd have no problem with exposing to the world (eg: no proper filenames like birthday.jpg
, no user_john.png
; ideally random values, but sequential ones (like mysql SERIAL
s) are probably tolerable enough.
Create a new "empty" page or route, lets call it say /image.php
Now, in your original page (not the new /image.php
yet, but the one you already had), you'll query the database to determine which images you want to show, and you use the unique id for those images to output something like
printf('<img src="/image.php?id=%s" alt="">', $imageID);
That <img>
tag will cause the user to automatically make an additional request to that new /image.php
page, in order to download the image.
Inside /image.php
, you'll take the requested ID from $_GET['id']
. then you'll query the database to see if that is an image this person should be able to access (and perhaps also determine what the filename
is, on the server).
lets say your queries determined that:
$allowAccess = true;
$filename = '../imgstorage/756345343465r563523.png';
Now you just make php send out some headers to identify the upcoming data as being an image, and then just pass the file through:
if ($allowAccess && file_exists($filename)) {
Header("Content-Type: image/png");
Header("Content-Length: " . filesize($filename));
readfile($filename);
Exit(0);
} else die('Go away');
and that's all there's to it.
The files can be located anywhere; both inside or outside the webroot (makes no difference), but PHP does need to have (filesystem)permissions to read from those files of course.