I am trying to download a binary file from the server that uses PHP.
Somehow it randomly adds one byte at the front of the file, when downloading it:
Result download (Hex editor image):
Expected result download (Hex editor image):
Things i have tried:
1. Headers aproach try 1
$filename = 'spss-export.sav';
header("Content-Disposition: attachment; filename=survey_2_SPSS_syntax_file.sav");
header("Content-type: application/download; charset=UTF-8");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
readfile($filename); // do the double-download-dance (dirty but worky)
exit;
2. Header aproach try 2
$filename = 'spss-export.sav';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($filename) . "\"");
readfile($filename); // do the double-download-dance (dirty but worky)
exit;
3. Laravel response download
$filename = 'spss-export.sav';
return response()->download($filename);
Header aproaches produce files that only have the random byte at the begining, but laravel aproach produces the random byte and one missing byte at the end of file. Anyone knows what might be the problem?
Found an answer myself:
You have to add ob_end_clean() before the file output. The laravel framework was somehow adding an extra space for files.
Reference if this doesnt work:https://drupal.stackexchange.com/questions/163628/extra-space-at-beginning-of-downloaded-image/163644#163644
Related
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..
I have a site where I'm using the following code to force a file download via PHP:
$ZipData = file_get_contents($zipFilename);
$ZipSize = filesize($zipFilename);
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=".$ZipTitle.".zip");
echo $ZipData;
While this works perfectly in Chrome and Firefox, it simply does nothing in Internet Explorer. While Googling I found a potential solution and changed the code to as follows:
$ZipData = file_get_contents($zipFilename);
$ZipSize = filesize($zipFilename);
if (strstr($HTTP_USER_AGENT,"MSIE")){
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-type: application-download");
header("Content-Length: $ZipSize");
header("Content-disposition: attachment; filename=".$ZipTitle.".zip");
header("Content-Transfer-Encoding: binary");
}else{
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=".$ZipTitle.".zip");
}
echo $ZipData;
But still no luck. I don't know why it's failing, nor where to start looking for errors or problems, is this just some I.E. bug I'm unaware of? Where should I start trying to find a solution?
Note: $ZipTitle will always be 'TexturePacker_Pack_xxx' where xxx is an incremented number. $ZipFilename is an existing zip file which is unlinked AFTER the file is sent to the browser.
Edit: The site and code in question are in action on http://www.texturepacker.net
Your Content-Length header seems to be incorrect. PHP filesize expects a string and returns an int.
Change it to actually get the size of the file on disk:
$zipFile = "C:\ZipFile.zip";
header("Content-Length: " . filesize($ZipFile));
I have the following code to push a zip file for download.
$filename = "ResourcePack_".time().".zip";
$destination = $basepath."downloads/$filename";
if($this->createdownload($files,$destination,false)){
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Length: ". filesize("$destination").";");
header("Content-Disposition: attachment; filename='$filename'");
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
ob_end_flush();
#readfile($destination);
if(file_exists($destination)){
unlink($destination);
}
}
I know the createdownload function is working to generate the zip file just fine because I see the file being created on the server. The problem is file is being written to the browser as a bunch of garbage instead of opening a download stream. Am I missing something in my headers?
EDIT
I was right. My problem is not with the php, but that calling the php file that generates this code via a JQuery $.ajax call is the problem. Using $.ajax automatically sets the Accept-Encoding request header to values incompatible with zip files. So, intead of using $.ajax I just used a simple window.open javascript command to call the same php page and it works just fine with the headers.
try to put a die after the #readfile
and remove the #, to see if you have any other error related with the file reading.
i have some code doing the same thing and this works for me:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-type: application/zip');
//header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($destination));
readfile($destination);
die();
try passing proper type for that file. I think its fileinfo mime type see http://www.php.net/manual/en/ref.fileinfo.php
header("Content-Type: $file_type");
Also you have semicolon after octet-stream remove it
header("Content-type: application/octet-stream");
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();
I would to know the command in a PHP script to get in output and save a file from my site.
Thanks
See here for a good description of how to force the output of a php script to be a download.
The basics of it are:
// Set headers
header("Cache-Control: public");
header("Content-Description: File Download");
header("Content-Disposition: attachment; filename=" + $filename);
header("Content-Type: application/zip"); // or whatever the mime-type is
// for the file you want to download
header("Content-Transfer-Encoding: binary");
// Read the file from disk
readfile($full_path_to_file);
As an addition (provided by Gordon's comment), see the 1st example on the php documentation here
At the End of the files or used in clicking files, you can add this
$filesh = "check.xls";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=".basename($filesh));
header("Content-Description: File Transfer");
readfile($filesh);
if you got any header using problem means, top of the file you can add ob_start(); function
If you mean getting output, contents from other site or location, this what you need file_get_contents