Force directly linked file to download - php

Is there any way to provide a direct link to a file and force the browser to download it using PHP?
E.g http://www.website.com/directory/file.jpg
We're dealing with huge files here and Chrome in particular seems to have a problem rendering the image, so all the user sees is a blank screen when visiting the file directly. Even though they can still right-click in the blank screen and download the file it's confusing.
We used to output the files from PHP but we ran into memory problems so switched to providing a direct link instead. The files go up to about 5GB, they aren't all images. We have zips, PDFs, PSDs etc.
Currently, the file is requested through a PHP script which accepts the ID of the file and get its URL. The PHP script then redirects to the user to full URL of the file.
How can we ensure that downloads are forced and we don't run into memory issues with the larger files?
Thank you

Just use X-Sendfile but you need to configure it first ... using XSendFilePath
if (file_exists($file)) {
header("X-Sendfile: $file");
header("Content-Type: application/octet-stream");
header(sprintf("Content-Disposition: attachment; filename=\"%s\"", basename($file)));
exit();
}
Note* Please ensure $file is properly escaped before you verify and serve the file
XSendFilePath only works on Apache for other servers please see : Caching HTTP responses when they are dynamically created by PHP

You need to set the headers for force download
$file = 'upload_directory_path/'.$image_name;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}

<?php
//file path
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}

Related

force to download zip from server is not working

I have tried to download file from server using below code but it not downloaded. It shows only content in browser
<?php
if(file_exists($zipName))
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=\'Uttam_Solanki.zip\'');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($zipName));
readfile($zipName);
exit;
}
?>
you need to change role in .htaccess
add application/octet-stream zip
your content-type must be `application/zip
here is a similar approach:
send zip file to browser / force direct download
How are you triggering this script?
If by link, maybe using download attribute would help?

php files to be downloaded displayed in browser instead of downloaded

I am trying to get a text file to download using a PHP script but when my script runs the file contents are displayed in the browser window. I tried this solution: Why downloaded file is not downloaded instead it is shown in browser?
However the code I have already has a content length header. This is my PHP code (which I obtained from another post 1 and modified for a text file)
$file = 'file.txt';
header('Content-Description: File Transfer');
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
Browser output of text file contents
I tried to copy an example from php.com for a pdf file and I get the same symbols as in the post I linked.
I am not sure why this is happening. I am running MAMP 3.5 with PHP version 5.6.10 on Chrome.
This has really baffled me since so far I have been able to find solutions online for everything I have done. As far as I can tell, what I am doing is correct so any advice would be much appreciated.
Many thanks,
Nehal Patel
RESOLVED (9/4/15) with guidance from Marcus:
removed flush() an ob_clean().
$file = 'file.txt';
header('Content-Description: File Transfer');
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
Try changing your content-type to octet/stream
header('Content-Type: application/octet-stream');

Files corrupt when downloaded through php header

I have a download link on my website from where we can download attachments. The pdf file is downloading perfectly but the images, docs and zip file are downloading as corrupt.
Below is the code which I am using for download. The code is working fine in my local pc but not on the server.
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($FilePath));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($FilePath));
readfile($FilePath);
exit;
The corruption occurs if your php script echoes anything before your headers.
Try using the same code, but in a separate php script.
Try adding
header('Content-Transfer-Encoding: binary');

php header issue when downloading zip

I'm trying to make php download a .zip file using this code:
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: ' . filesize($file));
readfile($file);
$file is right.
I have two problem with this script:
If I use header('Content-Length: ' . filesize($file)); the download is corrupt with 0 bytes file.
If I comment this line, the download looks good on ubuntu.
If I use mac OS to download this file, after opening the .zip it extracts .cpgz file (for what I read is when the zip is corrupt)
I've tried all kind of headers to make this work, but the problem is always on that header.
My question is: how can I make this work on all OS?
I use this for the purpose of downloading any kind of file using one generic PHP-script:
$base = "/path/to/downloadable/files";
$file = "myArchive.zip"; // or anything else
if(file_exists($base.$file)){
header('Content-Description: Download');
header('Content-Type: '.mime_content_type($base.$file));
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Length: ' . filesize($base.$file));
echo file_get_contents($base.$file);
}
This works fine for me with almost every kind of file (including .zip).

How to prevent documents from direct access

Hi we have a web application with document repository in php and web server is apache. How can I prevent access to these documents file directly using url, so that only our users can acceess the documents after login. The url for accessing the documents is also being displayed in google search result.
Don't store your files in your web root. Keep them outside of your web root and refer to them via a PHP file. That file will authenticate the user to verify that you want them to be able to download the file and allow them to see it. Otherwise it will prevent the from occurring or load an error message instead.
HTML:
Download
Sample PHP (download.php):
<?php
if (!isset($_SESSION['authenticated']))
{
exit;
}
$file = '/path/to/file/outside/www/secret.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
?>

Categories