PHP Force Download Help - php

I've been wrestling around with this for awhile now. I am trying to make it so when a user click a link it will force a download. Here's my code so far:
<?php
function Download()
{
$fullpath = $_SERVER['DOCUMENT_ROOT']."front.dwg"; //Full path of document
$filename = "front.dwg"; //Document file nmae
$mm_type="application/octet-stream";
header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($fullpath)) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary\n");
}
?>
<html>
<body>
Test
</body>
</html>

Your going to need to pull out your function and save it as "download.php"
Then just have a link that goes to it:
<a href="download.php">
Download.php should look like this:
$fullpath = $_SERVER['DOCUMENT_ROOT']."front.dwg"; //Full path of document
$filename = "front.dwg"; //Document file nmae
$mm_type="application/octet-stream";
header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($fullpath)) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary\n");

PHP is not a client-side function. You can't say onclick="somePHP".
You need a separate PHP script where you will force your download in, and simply link to that script.
In this script, you also need to actually output the file contents.

You need to set the appropriate calls to header first. These have worked for me:
header('Pragma: public'); // required
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header("Content-disposition: attachment; filename=\"{$filename}\"");
header("Content-Type: {$mime}"); // also works with file extension
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($filename));
readfile($filename);
die();

You can never FORCE a download. You can change the window location to the download file and it will prompt them, but if you could force downloads, there would be some major security issues.

First, your $fullpath may not contain the data you expect, because you did not insert a forward slash ('/') before the filename. This is correct:
$fullpath = $_SERVER['DOCUMENT_ROOT']."/front.dwg";
You can check the contents of $fullpath using error_log( "Fullpath: $fullpath" ); or echo "Fullpath: $fullpath\n".
Second, you need to make the PHP portion of your code a standalone script. You will not be able to embed PHP function calls in Javascript. All of your PHP executes before the Javascript runs, so you need a way to call the PHP separately.
Third, you should verify that the file exists and is readable using file_exists() and is_readable(). If PHP reports that the file does not exists, you should specify the full path. If it is not readable, you can change the file permissions to allow your PHP script to read it.

Related

Get zip file from url (PHP)

I have a zip files that I want users to be able to download. The trick is I don't want the users to see what the url is and I don't want to download the file to my server.
So I want users to click a link like this:
http://example.com/download/4
which server-side accesses my S3 bucket with this url:
https://s3.amazonaws.com/my-bucket/uploads/4.zip
I've tried cURL, using S3 methods, and various headers() in my download($file_id) function but can't get this to work. This has to be easy, right?
Your right, its quite easy. Probably you will have to write something like this:
$path = '/my-bucket/uploads/4.zip'; // the file made available for download via this PHP file
$mm_type="application/x-compressed"; // modify accordingly to the file type of $path, but in most cases no need to do so
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");
readfile($path); // outputs the content of the file
exit();
You set various headers to make your user download the .zip. Afterwards you put your file into the output buffer with readfile() Afterwards you end your script with exit() for security's sake. This should work for you! Remember to change the path to your file.
Thanks #Xatenev for the help. This is actually what worked for me:
$path = '/my-bucket/uploads/4.zip'; // the file made available for download via this PHP file
$mm_type="application/zip"; // modify accordingly to the file type of $path, but in most cases no need to do so
header("Content-Type: " . $mm_type);
header('Content-Disposition: attachment; filename="'.basename($path).'"');
readfile($path); // outputs the content of the file
exit();

PHP: Download a file on button click?

I created a form, which, when a contained button is clicked, should open a download dialog to download a certain file. The file is placed on the same server.
I tried:
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=" . $file . '"');
Where $file is a local path + the file name, for example c:\mypath\myfile.xls. This does not work though. It offers me a file, but its not a valid file. How else could I do that?
Note: I wrote c:\ because its still on my local machine for testing.
Thanks!
Try this
header("Pragma: public", true);
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename=".basename($file));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
die(file_get_contents($file));
I think file_get_contents() function is no longer work with PHP 5.0.3
Try this :
$path = "http://www.example.com/files/";
$filename = "abc.gif";
header("Content-Type:image/gif");
header("Content-Disposition: attachment; filename=".$filename);
header("Cache-control: private");
header('X-Sendfile: '.$path);
readfile($path);
exit;
PHP runs in server side, you can not download the files in clients machine.
Upload the files to server and then give that path for download.
Path must be refered from the site root...move the file
ex:
script path : C:/wamp/www/test.php
file C:/script.js
then:
if(file_exists('../../user.js'))
{
echo "OK";
}
Still a bad ideea..

PHP downloading excel file becomes corrupt

I have an excel file that i want a user to be able to download from my server. I have looked at a lot of questions on here but i cannot find a way to correctly download the file w/o corruption. I am assuming it is the headers but i haven't had a working combination of them yet. This is what i have right now and in the corrupt file that i receive i can see the column names of the spreadsheet i want but its all messed up.
$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header("Content-type: application/octet-stream");
header("Content-type: application/vnd-ms-excel");
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header("Pragma: no-cache");
header("Expires: 0");
readfile($filename);
edit: Solution I forgot to add that i was using Zend and it was corrupting the files when trying to use native php methods. My finsihed code was to place a link to another action in my controller and have the files download from there
public function downloadAction(){
$file = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="Spreadsheet.xls"');
readfile($file);
// disable the view ... and perhaps the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
}
try doing it this way
ob_get_clean();
echo file_get_contents($filename);
ob_end_flush();
For one, only specify Content-Type once. You can use the excel-specific header but the generic application/octet-stream may be a safer bet just to get it working (the real difference will be what the browser shows the user with regards to "what would you like to open this file with", but basic browsers can rely on the extension as well)
Also, make sure you specify Content-Length and dump the size (in bytes) of the file you're outputting. The browser needs to know how big the file is and how much content it's expecting to receive (so it doesn't stop in the middle or a hiccup doesn't interrupt the file download).
So, the entire file should consist of:
<?php
$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($filename));
header("Pragma: no-cache");
header("Expires: 0");
#readfile($filename);
$file_name = "file.xlsx";
// first, get MIME information from the file
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file_name);
finfo_close($finfo);
// send header information to browser
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="download_file_name.xlsx"');
header('Content-Length: ' . filesize($file_name));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
//stream file
ob_get_clean();
echo file_get_contents($file_name);
ob_end_flush();

How to download a php file without executing it?

im working on a content management system for that i have to download a php file using php code without executing. any one can help me on this
it is some thing like ftp. i have added the options to upload, edit and download a file. it is working fine. but while downloading a php file it is executed instead of downloading...
What i tried is:
<?php
$file = $_REQUEST['file_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));
include_once($file);
exit;
}
?>
You have to load the files content, write the content to the request and set the headers so that it's parsed as force download or octet stream.
For example:
http://server.com/download.php?name=test.php
Contents of download.php:
<?php
$filename = $_GET["name"]; //Obviously needs validation
ob_end_clean();
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ". filesize($filename).";");
header("Content-disposition: attachment; filename=" . $filename);
readfile($filename);
die();
?>
This code works without any modification. Although it needs validation and some security features.
The server somehow identifies file that should be executed instead of downloaded. You have to exclude the .php file you want to download from that handling. The easiest is probably to rename the file to .php.txt.
Otherwise you should be able to configure the server to not process that particular file, or the path were it is located. How you do that depends on which server you are running.
If such php file is located on the same server/website, then just open it as normal file, e.g. $fileContents = file_get_contents($filename);
If file is on another server, you have few possible options:
1) Access it via FTP (if you have login details and access)
2) Have special URL Rewrite rule on that server which will instruct web server to send file as plain text instead of executing it (e.g. somefile.php.txt)
3) Have special script on that server and by passing file name as a parameter it will return content of that file (e.g. http://example.com/showfile.php?file=somefile.php)
This is how to download a php file instead of executing it.
Trust me it works! ..download the file php with own risk :)
<?php
function downloadThatPhp($nameOfTheFile)
{
header("Pragma: public");
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/text/x-vCard");
header("Content-Disposition: attachment; filename=".basename($nameOfTheFile).";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($nameOfTheFile));
#readfile($nameOfTheFile);
exit(0);
}
// and this how to use:
// download that php file with your own risk :)
$file = $_REQUEST['file_name'];
$downloadThis = "http://domain-name.com/".$file;
if (file_exists($file)) {
downloadThatPhp($downloadThis);
}
?>
Hope this helps you bro :)
You can read alot about it on php.net/header, but to force a download, you can use a force-download header. This comment is amazing, check it out! :-)
if someone is looking to do this in his/her .htaccess file:
Header set Content-Disposition attachment
AddType application/octet-stream .php
or
<FilesMatch "\.(?i:php)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>

php image file download by code

This concerns downloading files with PHP
My php version is 5.3.5 and my apache is 2.2.17
I am trying to dowload files (pdf,jpg,tiff) that I have uploaded in my server, and they download with the same size and type but I can not see them. I am guessing they are not copied right. But when I open the original uploaded ones they work just fine.
I have seen almost all the questions that appeared as suggested and none of them answered the question, te only similar one is this, but still doesnt answer my question.
to download I am using this code
header("Content-type: application/force-download");
header('Content-Disposition: inline; filename="' . $dir . '"');
header("Content-Transfer-Encoding: Binary");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-length: ".filesize($dir));
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
readfile("$dir");
where $dir="62756d616769636e63/646973736572746174/ehddggh/1.JPG"
and $file="1.JPG"
can anyone give me a hint on what I am doing wrong, or give me a better solution to download files?
This smells like you are getting extra (spurious) content in your downloaded files.
Make sure you have no BOM headers, spaces, or anything else before your PHP open tags in your files; also, that you have no trailing whitespace or any other data after the closing PHP tags (if you close your PHP tags).
Also, clean up your code a bit: why multiple Content-Type headers? Why multiple Content-Disposition headers?
readfile($dir); // without the quotes?
Also, make sure that $dir actually exists
is_file($dir) or file_exists($dir)
Thank you all for the answers. I was calling the download as a function in a file with other functions in it so in the end I had to write a script alone, apart from other files. My problem was that I needed it to be safe and to only download a file if it belonged to the user and the user was logged in, so I send all the data I need, ciphered and inside the script I use a series of things to see if the owner is really the logged user. So if anyone wants to know this is the code I used and works perfectly.
<?php
session_start();
$a=$_GET['a'];
$parts=explode("-",$a);
$tres=$parts[0];
$nombre=$partes[1];
$dbcodletra=substr($tres,2);
if($dbcod!=$_SESSION["username"])$boolt=0;
if($ext==1) $extl=".jpg";
if($ext==2) $extl=".jpeg";
if($ext==3) $extl=".tif";
if($ext==4) $extl=".tiff";
if($ext==5) $extl=".pdf";
if($ext==6) $extl=".doc";
if($ext==7) $extl=".docx";
if($tipoproy==1) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if($tipoproy==2) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if($tipoproy==3) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if($tipoproy==4) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if (file_exists($dir) && $boolt) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($dir));
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($dir));
ob_clean();
flush();
readfile($dir);
exit;
}else echo "<meta http-equiv=\"Refresh\" content=\"0;url=misdocumentos.php\">";
?>
Paying it forward on a two-year old question...
I had a similar issue with corrupt downloads that could not be opened (when right-click & save-as worked perfectly). After reading #Jon's answer, I figured he was on to something. If you look at the docs for readfile (linked below), you will see an ob_clean(), a flush(), and an exit in their example. All of those will minimize leakage of extra character data in the response. I just copied their Example #1 and my problem was solved.
http://php.net/readfile
Your headers look messy, try just doing this:
header('Pragma: public');
header('Cache-Control: public, no-cache');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($dir));
header('Content-Disposition: attachment; filename="' . basename($dir) . '"');
header('Content-Transfer-Encoding: binary');
readfile($dir);

Categories