So I have this small PHP condition for a PHP download, it's been working fine for weeks then all of a sudden I noticed it's stopped working.
Rather than getting a download of the file, the users are getting a 0kb file instead.
I have checked the URL and it's still working as expected.
Here is the code
if ($refer == 'stackoverflow.com' || $refer == 'dev.stackoverflow.com') {
$fichero = $downloadUrl;
if ($fichero) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fichero));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fichero));
ob_clean();
flush();
readfile($fichero);
exit;
} else {
die("The File $fichero does not exist");
}
} else {
die("Sorry you must start the download from the website");
}
Now I know it's hitting the conditionals, because I am not getting any of the die statements and the file is still being offered as a download. This seems to have broken in Chrome and also IE(Edge). I have been doing some reading regarding headers and the only documentation on this proble I can find that appears to be relevant is the expires setting which i set to 0.
Am I missing an easy trick here?
Thanks a lot!
header('Content-Length: ' . filesize($fichero));
Was causing the issue, I should have debugged this a little more before posting.
This file needed write in order to suppress this warning
PHP Warning: filesize(): stat failed for
When removing
header('Content-Length: ' . filesize($fichero));
The code worked as expected, I tweaked with chmod on the file and re-enabled the above code and it fixed my issue.
Thanks
Related
I am getting an error. I am trying to read an attachment. It does work perfectly on most files but on few I get this error. The files have the same format and the location it is trying to read from is correct. I have tested it on windows explorer. This is way i am reading it:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename .'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($attachment_location));
ob_clean();
flush();
readfile($attachment_location);
exit();
This is the error I get
Warning: readfile(C:\Users\Public\asdgasd\4sf3\Suppliers\saf342\Files\Revit\2016\Seinätikas.rfa): failed to open stream: No such file or directory in C:\xampp\htdocs\web\downloadattachment.php on line 58
as Johndodo kind of references, you need to ensure that PHP is operating with the correct internal character set and encoding, so that it recognises the way the file is stored in your (windows) directory structure. See what character set your windows system is using and then use that same character set for PHP internal encoding.
Edit:
Logic process would be to:
Open file reference from email and convert the filename $var into the correct encoding.
Do the file_exists check
Proceed to pass the $var to the readfile function to open.
could you please provide the content of $filename and $attachment_location.
Could you please extend your code with this:
if (file_exists($file)) {
Your code goes here
....
exit();
}
Further things to check: Is the file readable by the webserver user (if you're using a websever).
Does the problem have an effect on files in which there are special chars in the filename ?
You should put a checker for see if the file exists in your filesystem.
if (!file_exists($filePath)) {
// Throw an exception or do something for alert the wrong path.
throw new Exception('File with this path is not available.');
} else {
// Do your amazing stuff here
}
So, I need a little help here. I have a site which hosts some mp3s. When users click on the download url, it links directly to a file called downloadmp3.php, which goes 2 parameters in the url...the php file is included below, and it's basically supposed to FORCE the user to save the mp3. (not play it in the browser or anything).
That doesnt happen. Instead, it seems like the file is WRITTEN out in ascii to the browser. It seems like it's the actual mp3 file written out.
Here is my downloadmp3.php file...please, what's wrong in this code.
It works on my local LAMP (Bitnami Wampstack on windows)....that is, on my local testing environment, it sends the file to my broswer, and I can save it. When I upload it to the real server, it basically writes out the mp3 file.
Here is the culprit file, downloadmp3.php...please help
<?php
include 'ngp.php';
$file = $_GET['songurl'];
$songid = $_GET['songid'];
increasedownloadcount($songid);
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: audio/mpeg');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
ob_clean();
flush();
readfile($file);
exit;
}
?>
By the way, this site only hosts mp3s - no other audio or file format. So, this downloadmp3.php script should ideally ask the user where they want to save this file.
Thanks for your help in advance.
I think the filename should be in quotes:
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
Change the content-type value to text/plain. With this browser wont recognize it and wont play the file. Instead it will download the file at clients machine.
Seems there is too many headers. I am sure they do SOMETHING... but this code works.
This code works with MP3 files.... downloads to a file. Plays without a problem.
if(isset($_GET['file'])){
$file = $_GET['file'];
header('Content-type: audio/mpeg');
header('Content-Disposition: attachment; filename=".$file.'"');
readfile('path/to/your/'.$file);
exit();
}
You can access it with ajax call, or this:
<a id="dl_link" href="download.php?file=<>file-you-wish-to-download<>" target="_blank">Download this file</a>
Hopefully this is of some use
Problem:
After download, the file doesn't contain the data.
i.e it become blank.
So please help me for this.
<?php
session_start();
include_once 'oesdb.php';
$id=$_REQUEST['id'];
if(isset($_REQUEST['id']))
{
$sql=executeQuery("SELECT * FROM file where id=$id");
$rows = mysql_fetch_array($sql);
$file =$rows['file'];
header('Content-Description: File Transfer');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile('uploads/'.$file);
exit;
}
?>
Why not create a HTACCESS file in uploads folder then states
Allow From 127.0.0.1
Deny From All
Then just create a URL, use HTML5's new download feature, do something like this:
click to download
It saves time trying to use PHP to make a download script.
try replacing this:
$file =$rows['file'];
by this:
$file = "uploads/".$rows['file'];
and this:
readfile('uploads/'.$file);
by this
readfile($file);
if still not working put the value returned by the readfile function
IMPORTANT
Please take in consideration the sql injection issues (see comment of Ondřej Mirtes)
The problem is here:
header('Content-Length: ' . filesize($file));
Content-Length receives zero value and browser downloads zero-length file, as you told him. If $file is path relative to upload/, you should do this:
header('Content-Length: ' . filesize('upload/'.$file));
Be sure that filezise() returns correct size and readfile() realy outputs it.
But the other problem is that you mentioned UPLOAD folder and using uploads. They are not same and case is important. Also, may be using relative paths in 'uploads/'.$file is not a good idea, it is better to use absolute path. For example, '/var/www/upload/'.$file.
I have a script that downloads a large file (1.3gb) using readfile().
If I create a .php page with just the script on it it works fine, but if I place the same script in a Snippet and place it on a page nothing happens.
Is ModX blocking the download some how? Any advice would be great thanks!
EDIT code:
$file = $_SERVER['DOCUMENT_ROOT']."/movie.mov";
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
};
Modx does have a maximum file size setting [Maximum upload size upload_maxsize] but that is for the file manager. I doubt that is your problem.
let's see the script and error logs.
UPDATE
just tested your little snippet out [with a couple of minor changes] ~ it works fine.
$base_path = $modx->config['base_path'];
$movie = 'frankenweenie-mrwhiskers_r640s.mov';
$file = $base_path.$movie;
if (file_exists($file)) {
echo 'file exists '.filesize($file);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
return true;
}else{
echo 'file does not exist';
return false;
}
using the $modx->config['base_path'] is not your problem, it worked using the server vars as well, it's just a good habit. as are the returning true/false modx expects it's snippets to return something whether true, false or $output ... also, not your problem it worked without.
Start looking at your php settings, I think possibly memory limit could be the problem. Check the php docs & see if it needs to have enough memory available to read a file that size. [even though it indicates 'size doesn't matter']
enable error logging in the script itself & check the server error logs.
It works with small files? Then look here: PHP readfile() and large downloads
Good luck!
When I use this code to download this image (only used for testing purposes), I open the downloaded image, and all it gives me is an error. i tried it in chrome. opening it with windows photo viewer, it says that it can't display the picture because it is empty???
here is the code:
<?PHP
// Define the path to file
$file = 'http://www.media.lonelyplanet.com/lpi/12553/12553-11/469x264.jpg';
if(!file)
{
// File doesn't exist, output error
die('file not found');
}
else
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
I've had a chance to work it out. Your problem is two-fold.
First, remove the www. from the url.
Second, remove the call to filesize($file) which is throwing an error because PHP doesn't know the size of the file before it downloads the file. (really, just remove the whole line)
Removing these two things, I was successful.
Replace ob_clean() with ob_end_clean()
You're still buffering, so none of the image contents get to the browser.
If your intention is just the download the file from a third party on click of a link, you could use the new property download in the anchor tag.
The code will look something like
<a download href="path/to/the/download/file"> Clicking on this link will force download the file</a>
It works on firefox and chrome latest version. Should I mention that I didn't check it in IE? :P
Replace:
ob_clean();
flush();
readfile($file);
With:
echo file_get_contents($file);