Force Download Files Broken Headers wrong? - php

if($_POST['mode']=="save") {
$root = $_SERVER['DOCUMENT_ROOT'];
$path = "/mcboeking/";
$path = $root.$path;
$file_path = $_POST['path'];
$file = $path.$file_path;
if(!file_exists($file)) {
die('file not found');
} else {
header("Cache-Control: public");
header("Content-Description: File Transfer");
header('Content-Type: application/force-download');
header("Content-Disposition: attachment; filename=\"".basename($file)."\";" );
header("Content-Length: ".filesize($file));
readfile($file);}}
As soon as I download the file and open it I get an error message. When i try to open a .doc file I get the message: file structure is invalid.
And when i try to open a .jpg file: This file can not be opened. It may be corrupt or a file format that Preview does not recognize.
But when I download PDF files, they open without any problem.
Can someone help me?
P.s. i tried different headers including :
header('Content-Type: application/octet-stream');

$fsize = filesize($yourFilePath);
$allowed_ext = array (
// archives
'zip' => 'application/zip',
// documents
'pdf' => 'application/pdf',
'doc' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
);
$mtype = mime_content_type($file_path);
if ($mtype == '') {
$mtype = "application/force-download";
}
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: $mtype");
header("Content-Disposition: attachment; filename=\"$asfname\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $fsize);
//then ur rest code

Your headers have no bearing on the actual content, so the issue is that there is something wrong with the actual content.
Also, you really shouldn't try to force a download by changing the Content-Type header. Leave it what it is supposed to be. Let the client decide what to do with it.

Make sure you don't output anything but the readfile() data: ensure that PHP code begins with <? at the very first symbol of the PHP file, and that there are no symbols after the closing ?> at the end of file, like a space or a newline (or remove the ?> altogether).

Open PHP file in NOTEPAD. Press "Save as" and choose "ASCI" file format. This helped in my case, because file was in UTF8 format and this was the cause.

Related

PHP says file does not exists when it does

Very lost right now. The filePath to this document is correct and is in the directory that is being printed by the echo but it keeps saying "file not found".
$fileName = 'driver.txt';
$filePath = $_SERVER['DOCUMENT_ROOT']."/driver.txt";
echo $filePath;
if(!file_exists($filePath)){ // file does not exist
die('file not found');
} else {
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$fileName");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
// read the file from disk
readfile($filePath);
}
Very silly mistake, tried downloading a different file and it worked. I then realized the file's name was driver.txt. So PHP was looking for driver.txt.txt. I appreciate all the help.

Download gzipped file through CloudFlare

I have a PHP file protector script:
.htaccess
RewriteEngine on
RewriteRule ^(.*).(zip|tgz)$ ../wp-file-protector.php?file=$1.$2 [QSA]
wp-file-protector.php
<?php
global $wpdb;
/** Make sure that the WordPress bootstrap has run before continuing. */
require( dirname(__FILE__) . '/wp-load.php' );
$current_user = wp_get_current_user();
if ($current_user->ID > 0){
$order = $_GET['order'];
$items = new_get_order_by_id_and_user($order, $current_user->ID);
if($items != false){
$file_enabled = true;
//Some authentication
$filepath = dirname(__FILE__).'/../downloads/'.$_GET['file'];
if($file_enabled && file_exists($filepath)){
$filename = basename($filepath);
$extension = end(explode('.', $filename));
ob_clean();
// http headers for zip downloads
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");
if($extension == 'tgz'){
header("Content-Type: application/gzip");
}else{
header("Content-type: application/octet-stream");
}
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath));
ob_end_flush();
#readfile($filepath);
}
}
}
I works fine with zipped and other files. The problem appears with gzipped files. I got unexpected results (also different results for Firefox download and open action).
I think I need some good header for the gzipped files. What should I use?
Also good to know that the request is running through the Cloudflare service, so maybe I should send out some header, which tells cloudflare server to not to gzip it.
I'm stuck :(
Update #1
header("Content-type: application/x-gzip");
This also doesn't work. When I choose save in firefox, it tells when opening that corrupted. When I choose open, I got a file without extension, but it seems tar as I can go deeper into the dir.

PHP make a zip file from 2 string variables

So what I am trying to do is take 2 strings and create 2 files. Then create a zip out of these files and let a user download them.
Here is what I have:
$string1 = 'Some data some data some data';
$string2 = 'Some data some data some data';
$zip = new ZipArchive();
$filename = "test.zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
$zip->addFromString("string1.txt", $string1);
$zip->addFromString("string2.txt", $string2);
$zip->close();
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: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize('test.zip'));
So far no luck. Any help is appreciated.
You missed the most important part - output the file! :)
Add:
readfile('test.zip');
to the end of the php file.
Also the calculation of the HTTP content-length header is wrong:
header("Content-Length: ".filesize($zip));
This will give you always 0 ( or false) as filesize expects a filename as its argument.
Change the line to:
header("Content-Length: ".filesize('test.zip'));
After doing both of this the zip will successfully download and contains the two files. For completenes, here comes the full working example:
$string1 = 'Some data some data some data';
$string2 = 'Some data some data some data';
$zip = new ZipArchive();
$filename = "test.zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
$zip->addFromString("string1.txt", $string1);
$zip->addFromString("string2.txt", $string1);
$zip->close();
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: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
// make sure the file size isn't cached
clearstatcache();
header("Content-Length: ".filesize('test.zip'));
// output the file
readfile('test.zip');
You have a PHP error (you probably dont have error reporting turned on or high enough error level).
the filesize() function takes a string not an object. filesize($filename) will work.
to turn on error reporting do:
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors', 1);
alternatively do this in php.ini
After all those header() calls, I think you want:
readfile($filename);

unknown file format on image download in php

i have this code for image download in php... works fine, image downloads but the problem is that it does not open in the place where it gets downloaded, and gives the error " Can't read file header...Unknown file format! "
<?php
$path = $row['img_url'].".jpg";
echo $path;
$filename = $path;
$ctype="application/.jpg";
// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header("Pragma: public"); // required
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-Type: $ctype");
// change, added quotes to allow spaces in filenames
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile("$filename");
exit();
?>
Change the content type
$ctype="application/.jpg"; //It's a invalid content type
to
$ctype="image/jpeg";
you should not be echoing anything before the header and try using header('Content-Type: image/jpeg');
Try using image/jpeg MIME type instead of application/.jpg
Your content type is wrong. Try to use $ctype="image/jpeg";

Path Name and Zip File Name showing when downloading Zip file In PHP

I am trying to write a PHP program which delivers a zip file for download. I have searched on the internet and tried all the solutions but my issue is not getting solved.
My problem is when the zip file is downloaded to a user's computer the entire path is displayed as the name of the zip file.
For Example:
Path to the Zip File: "http://www.websitename.com/folder1/folder2/"
Name of Zip File: "zbc123.zip"
When the Browser downloads the zip file, the Name of the file is as follows:
http-_www.websitename.com_folder1_folder2_zbc123.zip
I do not want the path to be the name of the downloaded zip file.
I only want the actual zip file to be displayed.
Here is my codespec:
$m_item_path_name = "http://www.websitename.com/folder1/folder2/";
$m_zip_file_name = "zbc123.zip"
//Combining the Path and the Zip file name and storing into memory variable
$m_full_path = $m_item_path_name.$m_zip_file_name;
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: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$m_zip_file_name."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($m_item_path_name.$m_zip_file_name));
ob_end_flush();
#readfile($m_item_path_name.$m_zip_file_name);
Can anyone help me to solve this issue.
Any kind of help will be appreciated.
Thanks a lot.
try this:
<?php
$file_names = array('file1.pdf','file2.pdf');
//Archive name
$archive_file_name=$name.'Name_u_want.zip';
//Download Files path
$file_path=$_SERVER['DOCUMENT_ROOT'].'/files/';
zipFilesAndDownload($file_names,$archive_file_name,$file_path);
function zipFilesAndDownload($file_names,$archive_file_name,$file_path)
{
//echo $file_path;die;
$zip = new ZipArchive();
//create the file and throw the error if unsuccessful
if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE )!==TRUE) {
exit("cannot open <$archive_file_name>\n");
}
//add each files of $file_name array to archive
foreach($file_names as $files)
{
$zip->addFile($file_path.$files);
}
$zip->close();
//then send the headers to foce download the zip file
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=$archive_file_name");
header("Content-length: " . filesize($archive_file_name));
header("Pragma: no-cache");
header("Expires: 0");
readfile("$archive_file_name");
exit;
}
?>

Categories