I have a simple script that allows someone to download a movie file to their device. The code works well on everything I've tested except for Andriod. The Android device butchers the name and the file extension. It might call the file 2.qt or .bin. Why is this failing?
<?php
if(isset($_GET['filename'])) {
header('Content-Description: File Transfer');
header('Content-Type: movie/quicktime');
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");
} else {
echo "Link: <a href='test.php?filename=test.mov'>Download Video</a>";
}
?>
Because Android doesn't natively support Quicktime, an Apple technology. It's also very possible that the client used to download this app isn't respecting the filename set on the http envelope as the name it uses to write the file to the filesystem, as there is nothing forcing it to.
The problem was that the filenames had spaces, and Android doesn't like that. I removed the spaces and everything is fine.
Related
I want to give a file to a person based on the users rank so I need to hide the files in a directory which is hidden.
I'm using Plesk and my structure looks like this:
api (reachable from https://api.pexlab.net)
cloud (reachable from https://cloud.pexlab.net)
default (reachable from https://pexlab.net)
error_docs
hidden (not reachable)
My PHP script is located in:
api/hub/Test.php (reachable from https://api.pexlab.net/hub/Test.php)
I have tried this:
# In Test.php
downloadFile("../../hidden/hub/download/assets/user/main.fxml");
# Function:
function downloadFile($file) {
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
This method works but I want to redirect to this file (show it) and NOT download it. So I have tried using this:
header("Location: ../../hidden/hub/download/assets/user/main.fxml");
But this tried to redirect to https://api.pexlab.net/hidden/hub/download/assets/user/main.fxml which is invalid.
The only difference between "viewing" and "downloading" a file is what the browser does with the data. Ultimately, that's in the hands of the user, but the server can indicate what it would like to happen.
I suspect you have copied these lines without really understanding what they do:
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));
These are all instructions to the browser telling it what to do with the data you send.
The Content-Disposition header is used to tell the browser "rather than trying to display this content straight away, suggest the user saves it in a file, with this name". To use the browser's default behaviour, you would simply leave off this header, or give it the value inline.
The Content-Type header tells the browser what type of file this is. The value application/octet-stream means "just a bunch of bytes, don't try to interpret them in any way". Obviously, that would be no good for viewing a file in the browser, so you should send an appropriate "MIME type", like text/html or image/jpeg, as appropriate for the file you're serving. I'm guessing "FXML" is an XML-based format, so text/xml might be appropriate; or if it's human readable and you just want it displayed without any formatting, use text/plain.
I've searched alot for that and nothing works for me. The Problem is that the file got displayed in the Browser. It includes JSON, but is an .locx file (needed for an APP). No not my APP so i cant change that. I've tested so much variations of Content Types and Encodings, but nothing helped me out. That is my Code.
<?php
function DownloadFile($file) {
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
DownloadFile('storage/3-3-2.locx');
?>
Thanks for reading!
// UPDATE
It works on another Server, and as written in the comments the Script works very well, but what i have to change in the server configuration that it works for me too?
It happens , while uploading the file.
While uploading the file encoding changed from utf8 to iso.
How do I make php force download a file. I have a file named song1, which is a song, in the file songs. so from the page I am at it is song/song1. How do I make php download the file as soon as the php is ran?
You have to send out some HTTP headers:
header('Content-disposition:attachment; filename=song.mp3;');
Then you have to pull the song data with for example file_get_contents(). And finally use a die() or exit() to avoid adding extra data.
Side note: The above code will not work if you've already sent out HTTP headers (wrote out some whitespace characters, etc), so put it directly after <?php if you can.
Try below code
$file='song1.mp3';
if (file_exists('song/'.$file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('song/'.$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('song/'.$file));
ob_clean();
flush();
readfile('song/'.$file);
}
It will directly download file.
I'd like users to be able to view files (I need to research this further, PDF/doc viewer, vid player etc) on the site before choosing to download them. Any suggestions on suitable methods?
The main question though is allowing them to download files.
I read on another SO post that this:
<?php
$file = 'monkey.gif';
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
is suitable however I'll be pulling the file name from the database. I'm thinking of using a standard download page so that download.php?filename=thisFileToDownload can pass the filename along.
The other issue is that there are different file types such as images, videos, excel, docs and pdfs etc etc. Are there any problems that I might run into with this?
Thanks for any help
I'm using PHP to generate a PDF via browser for my web-application. Recently, the client changed the webserver to Apache and now this feature is no longer working. Instead of generating the PDF, the browser is showing the PDF as text, just as it was ignoring Content-Type (that is set to "application/pdf"). In fact, I successfully simulated the problem by commenting the line setting the Content-Type in the source code.
I need ideas about where and what to look for, any help will be very welcome :)
Since you generate PDF files through PHP, you can try to add these headers:
$file_default = 'default filename you want to appear when the user downloads.pdf';
$file_location = '/path/to/file.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file_default);
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file_location));
ob_clean();
flush();
readfile($file_location);
I guess you'd have to force apache to download PDF content rather than showing:
check this: http://www.thingy-ma-jig.co.uk/blog/06-08-2007/force-a-pdf-to-download