I'm trying to make a distant client able to download an existing file(csv) named "source.csv" in my local machine using php.
After downloading the file the client should have a file named sourceCopy.csvwith the same content as the source file.
Here's what I've tried :
$file_url = 'source.csv';
header('Content-Type: application/csv');
header("Content-Transfer-Encoding: Binary");
header('Content-disposition: attachment; filename="sourceCopy.csv"');
readfile($file_url);
The file is downloaded but it doesn't match the source file !
I have this code to download a Zip file from the server:
<?php
$path_parts = pathinfo($_GET['a']);
$file_name = $path_parts['basename'];
$file_path = 'temp/' . $file_name;
if (file_exists($file_path)) {
$size = filesize($file_path);
header('Cache-Control: must-revalidate');
header('Pragma: public');
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file_name");
header('Expires: 0');
header("Content-Type: application/zip");
header("Content-length: $size");
header("Content-Transfer-Encoding: binary");
// read the file from disk
readfile($file_path);
}
else
echo 'File does not exists';
?>
The files are stored in a /temp folder and the curious thing is that if I download a TXT file, it downlads OK, but if the file is a ZIP file then it downloads an empty file. Even if I change the extension of the ZIP file to TXT it still downloads empty, but any other file download just fine. What could be causing this behavior?
In fact, it downloads any other file but the ZIP files in the folder.
It may be the file size, not the extension. Look in your php.ini file and see what these values are set to. If your file is larger than these, this would explain it.
post_max_size=5M
upload_max_filesize=5M
The problem is that PHP is not reading the ZIP files generated by the Java App that produces them. But, any other ZIP file is being read.
As I am using Java to create the ZIP files, I had to replace the method by this one posted here (https://www.mkyong.com/java/how-to-compress-files-in-zip-format/). It now works normally.
Try to use
header("Content-type: application/octet-stream");
instead of
header("Content-Type: application/zip");
This might be a duplicate but I have searched for the solution for so long and I still could not solve my problem. I have a localhost server where it stored some pdf files for download.
I implemented the following function to force the download:
if(isset($_POST['dlPDF']))
{
$file = $_SERVER['DOCUMENT_ROOT'] .'/Upload/'.$pdfName;
header("Content-Type: application/pdf");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$pdfName");
header("Content-Transfer-Encoding: binary");
// read the file from disk
readfile($file);
}
However I could not open the pdf file properly since it says "the pdf file is not correctly encoded".
FYI, the downloaded pdf file is always a few Kb larger than the original file.
Please kindly let me know if there is anything I can do to make the pdf readable and I appreciate your help.
I have a code which force download a pdf file. Code below
$file_name = 'Bv_Ebook.pdf';
$file_url = 'http://' .$_SERVER['HTTP_HOST'].'/sites/default/files/'. $file_name;
header('Content-Type: text/html');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
This code works on our beta server and the pdf is downloaded and can be opened.
On our live server same code downloads the pdf but pdf file cannot be opened, it says:
Unable to open document
File type plain text document (text/plain) is not supported
I have gone though force download pdf and apache headers setting but nothing seems to work.
Any idea what could be the issue?
Check file permission using is_readable() to check if the file is accessible or not. If accessible then check below :
Can you please try to modify your headers to the following:
//We'll be outputting a PDF.
header('Content-type: application/pdf');
//PDF name.
header('Content-Disposition: attachment; filename="'.$file_name.'"');
Then do a file read or what ever, in my case I have used file_get_contents(file_path) + echo to display the content and worked as a charm.
I'm trying to use the following code to create a zip file from a directory and serve it to the user via an http download:
// write the file
file_put_contents($path . "/index.html", $output);
// zip up the contents
chdir($path);
exec("zip -r {$course->name} ./");
$filename = "{$course->name}.zip";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' .urlencode($filename));
header('Content-Transfer-Encoding: binary');
readfile($filename);
I am able to create the zip file, but downloading it over http is not working. If I download the zip file that's created using an ftp client then Mac's Stuffit Expander unzips the files just fine, but if I download it over http, the mac unzipper creates an endless loop. What I mean by this is say the file I download is called course.zip, then unzipping the file gives course.zip.cpgz and unzipping that file gives course.zip again..and on and on.
Anyone have any ideas?
Thanks!
I had this problem and it turned out the downloaded zip file had a new line inserted at the very beginning.
Solved by using ob_clean and flush functions
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".basename($archive_file_name));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($archive_file_name));
ob_clean();
flush();
echo readfile("$archive_file_name");
Re-zipping it every time it is requested is not a good idea. Try doing that only if the ZIP file does not exist already.
If is a volatile file or just a single small file you want to transfer compressed, try using ob_start('ob_gzhandler') instead, simplier, smaller, cleaner. The file is transfered compressed, but it is saved in its original format by the client-side.
Specifying the Content-Length header is needed to allow the downloader to know the end of the file, allowing progress control, detection of corruption of the file and avoiding the hang of the HTTP session (if Connection is in Keep-Alive mode), maybe the lack of this header is the root of the problem.
As suggested by karim79, I'll put my comment as an answer: what happens if you change the MIME type from application/octet-stream to application/zip?
Also, I see you're using a command line zip program, but you don't check for success of the zip, and also don't check if the file exists before attempting to send it out to the end users browser. Try hard coding a file name, manually using zip to guarantee a properly formed zip file, and then see if your code will spit it to your browser properly.
What you're seeing is that the archive utility is not recognizing the zip file as a zip file, and tried to zip up the zip archive itself. The second operation simply unzips the first file created, so never actually opening the file at all. This is due to the zip being corrupted.
It is possible that the browser somehow mangled the zip file (newline conversions anyone?) during the download process. As mentioned, check the mime type and use the php header() to set the correct MIME type (application/zip).