Idrizi.A
Idrizi.A

Reputation: 12070

Start a download with PHP without revealing file URL

I want ta start a download using PHP, but I don't want the user to know the URL of the file which is downloading.

I have read a lot of answers in StackOverflow but all I have found are showing the URL of the downloaded file.

Here is what I want to do, in example:

This is the PHP file, the user will see this URL: http://website.com/download.php

This is the URL of the downloaded file, I don't want the user to see this URL: http://website.com/file.zip

Is there any way to do this?

Upvotes: 0

Views: 3531

Answers (3)

walkeros
walkeros

Reputation: 4942

Before renderring the page store the download url somwhere (in session for example) and generate some unique hash, which later you can use to identify which file should be downloaded:

$SESSION['file_download']['hash'] = md5(time) . '_' . $userId; // lets say it equals to 23afg67_3425
$SESSION['file_download']['file_location'] = 'real/path/to/file';

When renderring show the user following download url:

http://yourdomain.com/download_file.php?hash=23afg67_3425

If user clicks it you send the file to user, but only allow this one time or during the current session. By this I mean that you should create new source file called download_file.php with following content:

if ($_GET['hash'] == $SESSION['file_download']['hash']) {
  // send file to user by outputing the file data to browser
    $file = $SESSION['file_download']['file_location'];

    header('Content-Description: File Transfer')
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);

  // optionaly reset $SESSION['file_hash'] so that user can not download again during current session, otherwise the download with generated link will be valid until user session expires (user closes the browser)
} else {
  // display error message or something
}

Upvotes: 1

Dsda
Dsda

Reputation: 577

Try this:

    $file = './file.zip';
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"'); //<<< Note the " " surrounding the file name
    header('Content-Transfer-Encoding: binary');
    header('Connection: Keep-Alive');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));

Upvotes: 0

MikeVelazco
MikeVelazco

Reputation: 905

It depends of what do you want to hide. the URL will ever be shown to the user but if you dont want the user know which parameters (or values) send you can encode them and send them by a POST request via AJAX.

Upvotes: 0

Related Questions