I'm downloading a file through php script and everything work perfectly except one ugly truth. The downloaded file keep the same url and with original name appended. How do I maintain the same filename when file downloaded?
http://bachday.com/index.php?page=custom&file=mmailer/download.php?mfile=sample.docx
if (isset($_GET['mfile'])) {
$file = $_SERVER['DOCUMENT_ROOT'].'/oc-content/plugins/mmailer/pfile/'.$_GET['mfile'];
if (file_exists($file) && is_readable($file) && preg_match('/\.docx$/',$file)) {
header('Content-Type: application/docx');
header("Content-Disposition: attachment; filename=\"$file\"");
readfile($file);
/*
header("Expires: 0");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
echo (readfile($file));*/
}
else
{
header("HTTP/1.0 404 Not Found");
echo "Error 404: File Not Found: $file";
}
header('Content-Disposition: attachment; filename="name_of_file_here"') would have done the trick. You are passing the full path of the file there as header("Content-Disposition: attachment; filename=\"$file\""); since your $file contains full path. Instead just send the name of the file.
header('Content-Disposition: attachment; filename='.basename($file));
This line can perhaps solve the issue.
if (isset($_GET['mfile'])) {
$file = $_SERVER['DOCUMENT_ROOT'].'/oc-content/plugins/mmailer/pfile/'.$_GET['mfile'];
if (file_exists($file) && is_readable($file) && preg_match('/\.docx$/',$file)) {
header('Content-Type: application/docx');
header("Content-Disposition: attachment; filename=\"".basename($file)."\"");//use basename to extract filename from full file path
readfile($file);
/*
header("Expires: 0");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
echo (readfile($file));*/
}
else
{
header("HTTP/1.0 404 Not Found");
echo "Error 404: File Not Found:
$file";
}
Related
<body>
<?php
$zip = new ZipArchive;
if ($zip->open(getcwd() .'/read.zip', ZipArchive::CREATE) === TRUE) {
$zip->addFile(getcwd() . '/read.txt','/newname.txt');
$zip->close();
$file = getcwd() . '/read.zip';
// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"read.zip\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
readfile($file);
echo 'ok';
} else {
echo 'failed';
}
?>
</body>
I have following code and want to download zip file automatically that is being produced by this code when we run this page.
u need to add header for the client about file downloading. just see the manual example: http://php.net/manual/en/function.header.php#example-5315
<?php
$file = getcwd() . '/read.zip';
// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"read.zip\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
ob_end_flush();
#readfile($file);
I tried to write a php-script to create and download a zip file. When I tested the script on my localhost, the download works, but when it's uploaded to the server, things go wrong: instead of downloading the zip file, the content of the file is displayed in the browser.
Can somebody point me in the right direction?
The code
$zip = new ZipArchive();
$zip->open("$maand/zipfile.zip", ZipArchive::OVERWRITE);
$zip->addFile("$maand/ant/a_nb.txt", 'ant.txt');
$zip->addFile("$maand/lim/l_nb.txt", 'lim.txt');
$zip->addFile("$maand/oos/o_nb.txt", 'oos.txt');
$zip->addFile("$maand/vla/v_nb.txt", 'vla.txt');
$zip->addFile("$maand/wes/w_nb.txt", 'wes.txt');
$zip->close();
$filename = "zipfile.zip";
$filepath = "$maand/";
// 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-type: application/zip");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Length: ".filesize($filepath.$filename));
ob_end_flush();
#readfile($filepath.$filename);
you missing ob_start()
example:
header('Content-Type: application/csv');
header('Content-Disposition: attachement; filename="' . $download . '"');
ob_start();
$str = '';
if(file_exists($file) === true){
$str = file_get_contents($file);
}
ob_end_clean();
echo $str;
I have a file image.php that dynamically views an image inside a Zip folder.
So image.php?location=./folder/Hi.zip&file=image.jpg views the image.
I have another file downloadfile.php that forces download of file specified in the parametes.
downloadfile.php?location=.folder/&file=image.jpg* downloads the image*
What I need is to download the dynamically generated image (by image.php) using downloadfile.php.
downloadfile.php
<?php
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
$file=$_GET['file'];$ext=$_GET['ext'];$location=$_GET['location'];
header('Content-disposition: attachment; filename="'.$file.'"');
header('Content-type:"'.$ext.'"');
readfile("$location"."$file");
?>
image.php
<?php
function showimage($zip_file,$file_name)
{
$z=new ZipArchive();
if($z->open($zip_file)!=true){
echo "File not found";
return false;
}
$stat=$z->statName($file_name);
$fp=$z->getStream($file_name);
if(!$fp){
echo "Could not load image";
return false;
}
header('Content-Type:image/'.$_GET['type']);
header('Content-Length:'. $stat['size']);
fpassthru($fp);
return true;
}
showimage($_GET['zip'],$_GET['file']);
?>
Any suggestions??
In order to force browser to download an image file you can use the code from image.php
and just change the header
from
header('Content-Type:image/'.$_GET['type']);
header('Content-Length:'. $stat['size']);
to
header("Content-Transfer-Encoding: binary");
header('Content-Description: File Transfer');
header('Content-Type:image/'.$_GET['type']);
header('Content-Length: ' . $stat['size']);
header('Content-Disposition: attachment; filename=' . $file_name);
this will force user to download instead of display an image.
I have a code to download zip files:
$dl_path = './';
$filename = 'favi.zip';
$file = $dl_path.$filename;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/zips');
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-Type:application/download");
header("Content-Disposition:attachment;filename=$filename ");
header("Content-Transfer-Encoding:binary ");
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
there is root directory /public_html, the script is executing in root directory.
there is zip file in / directory.
i am trying to use the $dl_path as / but it is not working.
Please help.
$dl_path = __DIR__.'/..'; // parent folder of this script
$filename = 'favi.zip';
$file = $dl_path . DIRECTORY_SEPARATOR . $filename;
// Does the file exist?
if(!is_file($file)){
header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found");
header("Status: 404 Not Found");
echo 'File not found!';
die;
}
// Is it readable?
if(!is_readable($file)){
header("{$_SERVER['SERVER_PROTOCOL']} 403 Forbidden");
header("Status: 403 Forbidden");
echo 'File not accessible!';
die;
}
// We are good to go!
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
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-Type: application/download");
header("Content-Disposition: attachment;filename={$filename}");
header("Content-Transfer-Encoding: binary ");
header('Content-Length: ' . filesize($file));
while(ob_get_level()) ob_end_clean();
flush();
readfile($file);
die;
^ try this code. See if it works. If it doesn't:
If it 404's means the file is not found.
If it 403's it means you can't access it (permissions issue).
First of all check if your script is running under the correct directory by echoing dirname(__FILE__).
If it is running under public_html then you can change the code like this:
$dl = dirname(__FILE__). '/../';
But beware of security issue!
Check if you have read/write permission on the file and directory
Check the open_basedir restriction in php.ini (see How can I relax PHP's open_basedir restriction?)
Hope this helps
I currently have the following:
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($path)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo 'File not found';
} else if (!is_readable($path)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo 'File not readable';
} else {
ob_start();
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header('Content-Description: File Transfer');
header("Content-Type: octet-stream");
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header("Content-Length: ".filesize($path));
header("Content-Disposition: attachment; filename=\"".basename($path)."\"");
ob_clean();
ob_flush();
readfile($path);
exit;
The above code produces a file download of the correct file name, but with a twist.
The downloaded file has some html from the download page (headers being sent incorrectly?) then later in the downloaded document there is gibberish text (ex. OJQJ^J.??. WW8Num2z0) taking up several pages. Finally at the end of the .doc I can read some English which appears to be the correct text of the .doc, but with no formatting.
These issues persist in Chrome and Mozilla.
Any help would be greatly appreciated. Thanks in advance.
EDIT:
I began testing with a .doc that has only one line of text: "test"
The file can be opened manually from the directory in which it is uploaded to, and verified that it is not corrupt. However, downloading this file using any of the methods recommended thus far yields several pages of gibberish text (the real file is only 1 line). The actual text of the file, which is "test", is found on the very last of the 66 pages of gibberish, and it is found in this haystack: ?test ?"ᄚ? ᄚ?!ᄚn"ᄚn#ミn$ミn3P(20???՜.モラ+,??՜.モラ+,???Root Entry???????? ?F#CompObj????jOle ????????1Table????????????ᆬSummaryInformation(?????WordDocument????????????"$DocumentSummaryInformation8????????????[t????????????????
What are these?
header("Content-Type: octet-stream");
header("Content-Transfer-Encoding: binary");
Trim down your code to a working example and extend it from there. You do not need to set the status code, PHP does this for you. You do not need to set the Content-length either. Sending only this should just work:
$path = 'foo.dat';
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($path)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo 'File not found';
} else if (!is_readable($path)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo 'File not readable';
} else {
header("Content-Disposition: attachment; filename=\"".basename($path)."\"");
readfile($path);
}
}
Try this excerpt for the last else that is without any flushing functions
header("HTTP/1.1 200 OK");
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($path));
header("Content-Description: File Transfer");
#readfile($path);