I'm trying to write a php script that will check parameters passed in before it initiates a download to the client. I've started by attempting to just initiate a download:
<?php
$file = '/tticon.jpg';
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;
?>
When I navigate to this script it shows a blank page and nothing happens. How do I initiate a download?
Try using application/force-download as Content-Type. If you want to show the image in the brwoser you can use image/jpg.
header("Content-type: application/force-download");
Since the file's extension is ".jpg" I assume it's mime is image/jpeg.
Replace this line:
header('Content-Type: application/octet-stream');
with this:
header('Content-Type: image/jpeg');
If you really want to force the browser to download the file (which I find very unlikely, anyway):
Replace the line with this:
header("Content-Type: application/force-download");
Your $file looks suspect. Do you really have a tticon.jpg in the root directory of your server? Remember that PHP's file-functions operate on the FILESYSTEM of the server, not the WEB directories that Apache presents. PHP will not magically pre-pend your site's document root to that path. It's literally going to be looking in the root directory of the server's file system, NOT in the document root of your site.
Related
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?
Today i wanted to create some php script which will force download mp3 files directly.
File i want to download is placed in sounds folder and i can access to it via http://playall.pl/sounds/ThemadpixprojectBadChick.mp3
But when it comes to php script - function file_exists says, that this file is not on this server.
How can i fix it?
Code im using to download file
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file_name));
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;
And to get filename and file url
$file_name = ''.$sound['Sounds']['artist'].' - '.$sound['Sounds']['title'].'.mp3';
$file_name = preg_replace('/\s+/', '_', $file_name);
$file = 'http://playall.pl'.$this->webroot.'sounds/'.$sound['Sounds']['src_url'];
For file_exists($file) the variable $file needs the full path. And has to be a path on the filesystem, not a url for web location.
So you need something like:
$file = $_SERVER['DOCUMENT_ROOT'] . '/app/webroot/sounds/';
$_SERVER['DOCUMENT_ROOT'] gives you the filesystem path to your htdocs folder, so the rest needs to be relative from there.
Ok. The problem was very simple - i had a / in front of path. Now its working correctly. Thanks all for help!
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;
}
I have fried my brain all day on this. Researching SO until my eyes are bleary...I need to know: How do I access files placed outside the site root?
Background: Apache 2.0 dedicated server running Linux.
Code: PHP and MySQL
Reason: I want the files to be secured against typing in the file path and filename into a browser.
This can't be that difficult...but my splitting head says otherwise. Any help would be absolutely appreciated.
Have a look at the answers to this question, which seem to be doing more or less the same thing.
A quick summary: readfile() or file_get_contents() are what you're after. This example comes from the readfile() page:
<?php
$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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
I don't recommend allowing the $file variable to be set using user input! Think about where the filenames are coming from before arbitrarily returning files in the response.
are you trying to access files outside of site root? Then you can look at this link in stackoverflow.
And this is the official doc in Apache.
Otherwise you don't have to do special handling to prevent others from accessing files outside site root.
I am having trouble uploading a file to the user from outside of "public_html" which is the folder that everyone has access to thru http. Ex. www.website.com/ everyhting after the / is public_html. I'm sure you all know what I'm referring to.
So I have this script that should read a file (sample.pdf) from (server perspective) /images/protected/ but PHP won't find my file. Am I doing this wrong?
<?php
$file = '/images/protected/sample.pdf';
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;
} else {
echo "404 - FILE NOT FOUND!<br />\n";
echo "File: $file";
}
?>
Every time I execute this script I get the 404 - FILE NOT FOUND!<br />\n instead of a file download.
You have to supply the absolute system path. Currently, you're requesting a file at /images/..., rather than /var/www/hosts/whateverdomain/images/....
$file = $_SERVER['DOCUMENT_ROOT'].'/images/protected/sample.pdf';
If your file is really located at /images/protected/, make sure that you have sufficient permissions to read that file.
Turns out I am on shared hosting so the right "root" path for my website was /home/me/