1

I have image file here

/var/www/img/timetable.jpeg

URL is

www.mydomain.com/img/timetable.jpeg

But I don't want user know the real URL, I want user access the file like this

www.mydomain.com/get/timetable.jpeg

So I use PHP framework to intercept request, e.g. Fat-free

$f3->route('GET /get/@filename',
    function($f3) {
        $filename=$f3->get('PARAMS.filename');
        // here return/redirect the file
    }
);

But I don't want to use this way.

$f3->route('GET /get/@filename',
    function($f3) {
        $filename=$f3->get('PARAMS.filename');
        $attachment_location = 'img/'.$filename;

        header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
        header("Cache-Control: public");
        header("Content-Type: image/jpeg");
        header("Content-Transfer-Encoding: Binary");
        header("Content-Length:".filesize($attachment_location));
        header("Content-Disposition: attachment; filename=".$filename);
        readfile($attachment_location);
    }
);

I expect something like this, but this is redirect, user will know URL

$f3->route('GET /get/@filename',
    function($f3) {
        $filename=$f3->get('PARAMS.filename');

        header("Location: img/".$filename);
    }
);

Can I do that in PHP, is it call Forward?

CL So
  • 3,647
  • 10
  • 51
  • 95

2 Answers2

1

You can achieve this using couple of different solutions. Simplest is to use Apache's .htaccess rewrite rule. All the requests made to the image goes to an image-server.php file, that handles the requests.

/get/.htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule (.*) image-server.php?file=$1 [QSA,L]
</IfModule>

Do not host the image within the same directory. Your image-server.php will read the $_GET["file"] value and return the image from a protected directory.

<?php
# /get/image-server.php

header("Content-Type: image/jpeg");
$secret_location = "/var/www/html/images/timetable.jpeg";
readfile($secret_location);

This is a basic usage example. You should check $_GET["file"], ie. $secret_location="/PATH/{$_GET['file']}"; ensure that the image file exists, and then readfile().

So, your directory structure is:

/get/.htaccess
/get/image-server.php
/secret-location/images/timetable.jpeg

None of your images will have a real URL, because you will host the image outside of htdocs or public_html folder.

Bimal Poudel
  • 1,214
  • 2
  • 18
  • 41
  • I don't understand, the .htaccess file just prevent user to access img folder, but this is not a problem, because I will not public the image folder name, user don't know img folder name. I have also used .htaccess to rewrite url to `www.mydomain.com/get/xxxxx`. My question is how to return a file in `www.mydomain.com/get/xxxxx` – CL So Sep 07 '19 at 19:17
  • I edited the answer to mention entire contents of your image-server.php. – Bimal Poudel Sep 08 '19 at 06:40
  • I wrote same thing in my question, I don't want to use that. X-Sendfile is the exact solution what I want – CL So Sep 11 '19 at 06:44
0

Maybe this help:

function showImage($name){
    $file = basename($name);
    $path  = 'img/'.$file;
    $mime = mime_content_type($path);
    $types = [ 'gif'=> 'image/gif', 'png'=> 'image/png', 'jpeg'=> 'image/jpeg', 'jpg'=> 'image/jpeg'];
    // if allowed type
    if(in_array($mime, $types)){        
        if(file_exists($path)){
            header('Content-type: '.$mime);
            header("Content-Length: " . filesize($path));
            //echo file_get_contents($path);           
            readfile($path);
        }       
    }
}
Community
  • 1
  • 1
haski
  • 1
  • 1