Force Download a External or Internal File like jpg
Example method 1 for external or internal file:
https://example.com/photos/photo.jpg/download?force=true
https://pixabay.com/images/download/wintry-69661.jpg?attachment
Another, this method will generate the download link
https://www.pexels.com/photo/2755165/download/
I know this method 2: but I need the above method 1.
https://download.example.com/images/download.php?file=9284.jpg
I have multiple codes to force download like method 2. But I need method 1.
I'm using this PHP to force download for method 2
<?php
if(!empty($_GET['file'])){
$fileName = basename($_GET['file']);
$filePath = '/home/download.example.com/images/'.$fileName;
if(!empty($fileName) && file_exists($filePath)){
// Define headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$fileName");
header("Content-Type: image/jpeg");
header("Content-Transfer-Encoding: binary");
// Read the file
readfile($filePath);
exit;
}else{
echo 'The file does not exist.';
}
}
?>
Thank you
Related
I'm trying to download a .rar file from a cloud (for sake of simplicity I'm using my google drive storage), the file is downloading perfectly, but once i want to open the .rar file , it says that "the archive is either unknown format or damaged" , tried all methods even cURL ,but it didnt want to work,
Im just wondering what I'm missing in my code, thank you
<?php
$filename = 'stu.rar';
if ( file_put_contents( $filename,file_get_contents("mygoogleDriveLink/search?q=stu.rar"))) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//header('Content-Length: '.filesize($filename));
readfile($filename);
//print_r("this is ".$id);
exit();
}
else{
echo "err";
}
You may use file_put_contents to save the file to the server first, before you stream it to your browser.
if you do not need to stream to user's web browser, then you may remove the codes from start streaming to end streaming.
Please try the following:
<?php
// Initialize a file URL to the variable
$url = 'http://www.xxxxxxxxxxx.com/xxxxx.rar';
// Use basename() function to return the base name of file
$file_name = basename($url);
// Use file_get_contents() function to get the file
// from url and use file_put_contents() function to
// save the file by using base name
if(file_put_contents( $file_name,file_get_contents($url))) {
// File successfully saved in the server
// start streaming . The following is to stream and save to browser
$file_name = $file_name;
$file_url = $file_name;
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
/// end streaming
}
else {
echo "File downloading failed.";
}
?>
I have blob stored in Database and successfully converted it into PDF. I am using this code.
header('Content-type: application/pdf');
header("Cache-Control: no-cache");
header("Pragma: no-cache");
header("Content-Disposition: attachment;filename=".$this->pdfName);
header("Content-length: ".strlen($res[0]['comp_statement']));
$this->pdf = $res[0]['comp_statement']
echo $res[0]['comp_statement'];
There are two option in Content-Disposition ethier you can download it or show it on web page.
I do not want to show or download. I want it to place in zip directory which I am creating dynamically.
Here the code for zip archive
$zip = new ZipArchive;
$zipName = $this->currentCompYear.'.zip';
if ($zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
if(!$zip->locateName($this->currentCompYear)) {
$zip->addEmptyDir($this->currentCompYear);
}
if(!$zip->locateName($regionDir)) {
$zip->addEmptyDir($regionDir1);
}
if(!$zip->locateName($managerDir)) {
$zip->addEmptyDir($managerDir1);
}
$zip -> addFile($this->pdf));// I want to add my pdf file here
$zip->close();
ob_clean();
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=".$zipName);
header("Content-length: " . filesize($zipName));
header("Pragma: no-cache");
header("Expires: 0");
readfile($zipName);
Any Clue.
You dont need any of that header and echo stuff if you just want to store the contents to a file, use file_put_contents() to store the pdf, then pass the file name and not the contents to addFile() of your Zip function
https://www.php.net/manual/en/function.file-put-contents.php
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 am new to PHP and trying my hands into it. I am creating a file and writing back to it. Creating a file in some path and writing to it, works fine for me. But when i try to download the same file from the same path, its not getting downloaded instead I'm getting empty file.
header('Content-type: text/xml');
header("Content-Disposition: attachment; filename=".'check.xml');
header("Content-Length: " . filesize('./download/'.$_SESSION['user_name'].'/check.xml'));
readfile('download/'.$_SESSION['user_name'].'/check.xml');
exit;
Hi, Thanks for everyone. But I saw very unusual thing. When i downloaded the file, I didn't got the full file.
Why this case
Try removing ./ from the start of the filepath, like follows:
header('Content-type: text/xml');
header("Content-Disposition: attachment; filename=".'check.xml');
header("Content-Length: " . filesize('download/'.$_SESSION['user_name'].'/check.xml'));
readfile('download/'.$_SESSION['user_name'].'/check.xml');
exit;
With Linux file systems, ./ means the root, so that's the equivalent of / and ../ means the directory above the current directory. It's best to use absolute file paths, but simply removing the ./ should suffice.
You will also need to flush the write buffers of PHP using flush()
Here is a good working function to download a file
Here is a version adapted from that page:
public static function downloadFile($fileName) {
$filePath = $fileName;
$size = filesize($filePath);
// Taken from http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=\"$fileName\"");
header("Content-Transfer-Encoding: binary");
header("Accept-Ranges: bytes");
// The three lines below basically make the download non-cacheable
header("Cache-control: private");
header("Pragma: private");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Content-Length: " . $size);
if ($file = fopen($filePath, "r")) {
$buffer = fread($file, $size); // this only works for small files!
print $buffer;
flush();
fclose($file);
}
}
I downloaded this code to use as a download button.
<?
$filename = $_GET["filename"];
$buffer = file_get_contents($filename);
/* Force download dialog... */
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
/* Don't allow caching... */
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
/* Set data type, size and filename */
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . strlen($buffer));
header("Content-Disposition: attachment; filename=$filename");
/* Send our file... */
echo $buffer;
?>
The thing is, the name of the file ends up with the whole path in the file name, for example, this code:
<a href="download.php?filename=images/something.jpg">
Ends up with an image named "images_something.jpg"
I'd like to remove the "images_" from the final file name, so far I haven't had any luck.
Thanks for the help!
If you need the file name part without folder name, you have to use basename($filename)
http://php.net/manual/en/function.basename.php
basename()
$filename = basename($path);
p.s
Setting Content-Type several times may not be the best way to force a download. Also, I hope you're sanitizing that $filename argument before you use a file_get_contents.
p.p.s
Use readfile, don't cache it in the memory.
$filename = basename($filename);
header("Content-Disposition: attachment; filename=$filename");
Set your filename to only be the basename?
Don't do it at the top unless you change the variables though so your pathing to it still works.