I use a download handler to let the user access certain documents.
I've understood Android has got some problems, so I made this script:
$result['title'] = "Test week";
$result['extension'] = "docx";
$file = '../database/'.$_GET['id'].'.'.$result['extension']; //The path to my file of which I am certain it exists, for example '../database/5.docx'
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="DE '.$result['title'].'.'.strtoupper($result['extension']).'"');
readfile($file);
However, my old android phone still downloads the file as "File.bin" and the download fails, both symptoms of the source mentioned above. I only use two GET parameters, so now I'm really not sure what I've done wrong.
On other phones, the download works fine, so the actual $file path is correct.
Do not use spaces in filenames or replace them with %20. Url encode.
Related
I have a blob field in a database. In which i store values resulting from this:
mysqli_real_escape_string($mysql_link, file_get_contents($_FILES['file']['tmp_name']));
I created a script to download this file from database.
The script works and the file is downloaded. But there is an issue:
If the file stored there, is an image file, like "jpeg" or "png", everything is just fine. But if it is other type, as "PDF", for example, when i open it, the pdf reader can't read the file. Says that the pdf is damaged. I don't know why it's happening with some file types and not with others.
Here's the download script:
function download($filedata, $filename){
header('Content-Type: '.$filedata['mime']);
header('Content-Disposition: attachment; filename="' . $filename . "." . $filedata['extension']);
header('Pragma: no-cache');
ob_clean();
echo $filedata['data'];
exit;
}
$filedata is the fetched result from database. I also checked it and the values are correct, according to each file, and after all, the images are working perfectly.
It is really tricking me!
Assuming this PDF example execution, the var values would be as follows:
$filedata['mime'] = "application/pdf";
$filedata['extension'] = "pdf";
$filedata['data'] = the blob content;
$filename = uniqid();
Thx in advance!
UPDATE:
I ran a test with PDF files. Selected a set of working PDF's from my local machine, uploaded all, storing them in the database, using the file_get_contents() mechanism, cited above, then downloaded it all back, using the download script, also cited above. The results: some of the downloaded PDF files worked, some of them didn't.
A friend told me something about the encoding of the files. Which could explain the fact that some files, after download, works and some do not. Could it be? And how could i fix it?
UPDATE:
I used echo mb_detect_encoding($filedata['data']); exit; and all printed "UTF-8", for both working and not working files. So, it's not an encoding issue. Any other ideas?
I am saving a pdf file, and then attempting to download it using php.
The script seemed to work fine, but all of the sudden not anymore.
Can anybody see what I am missing?
PS: the file I am downloading is only 4.3kb big, so I assume that would be because it is not downloading at all. The actual file size should be bigger than this.
$pdf->output(ROOTDIR.'/modules/addons/statement_generator/reports/statement.pdf');
if($action=='print'){
$file_name = 'statement.pdf';
$file_url = "http://".$_SERVER['SERVER_NAME']."/modules/addons/statement_generator/reports/" . $file_name;
header('Content-Type: application/pdf');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
}
The $pdf->output() call will already send the PDF to the client. The file will not be saved to your local folder (Didn't you checked at least this?) because you have to pass "F" as the snd parameter.
After that you try to read from an URL (!!!!) that does not exists and which maybe return a nicely styled 404 html response. Two issues here:
Why are you using http when you have the local path used some lines above? Use the local path only!
The content returned by the URL is append to the already send PDF which ends in a document mixed of PDF and HTML (the 404 response) -> corrupted PDF
Conclusion: Use "F" as the 2nd parameter and use the same path for both writing and reading and not a mix of local path and URL.
I have a file with no extension on it, but I know it's a tiff. I want to be able to download this file via PHP.
I created a page with a link to another php page, which has the following content:
<?php
$imgPath = 'http://server/23700-b074137f-eb5c-45d6-87c2-13c96812345b';
header("Content-disposition: attachment; filename=invoice.tiff");
header("Content-type: image/tiff");
readfile($imgPath);
?>
When I click the link, I get a prompt to download invoice.tiff, but it's 0 bytes.
However, if I rename the file on the server to 23700-b074137f-eb5c-45d6-87c2-13c96812345b.tiff (and change the $imgPath), it works.
How do I accomplish this without renaming the file to include the extension?
It's possible the 'tiff' extension is registered as a known file type on the server, so when you rename and request the tiff it's permissions will allow you to open it. However, with no extension, the security is probably stopping you from reading it, as mentioned by 'Mike B' above. To check this try just entering the file name in your browser address bar and see if it opens, both with and without the 'tiff' extension. There is no workaround for getting past the security issue, short of changing the severs security which would be very bad.
You are retrieving the file from a URL, therefore activating the 'fopen wrappers' in readfile. In general, you should not do this, especially when working locally since it invokes a lot of unnecessary overhead and (in this case) unwanted 'magic' behaviour.
Just use readfile on the local path to the file, and it'll be fine, or use die(file_get_contents($imgPath)) instead of the last line to circumvent PHP's native behaviour.
It works for me:
$imgPath = 'http://server/23700-b074137f-eb5c-45d6-87c2-13c96812345b';
$f = fopen($imgPath, "r");
header("Content-disposition: attachment; filename=invoice.tiff");
header("Content-type: image/tiff");
fpassthru($f);
You should also add the content-length header like so:
// untested code
header('Content-Length: '.strlen(stream_get_contents($imgPath)));
First post. I'm working on a project for a client where they have pdf files uploaded to a file structure (LAMP Stack) but the files have no extensions on them. Under the assumption that those files have to be PDF how would I get the browsers to understand that, and open them accordingly? Obviously with adding the file extensions this would suddenly work but I can't change the way their system works, it would result in too many changes and they are on a tight deadline. As for saving a temporary copy somewhere, I could do that, but I was hoping for a better solution. Is there a way to suggest to the browsers that they open a file a certain way?
Any thoughts guys/gals?
You just set the application type and file name in the headers, like so:
// This points to the file in question, note that it doesn't
// care whether it has an extension on the name or not.
$filePathOnDisk = '/path/to/your/pdffile';
// You can make this whatever you like, it doesn't have to
// be the same as the file name on the disk! This is the name of the file your end
// user will see when they are asked if they want to save. open, etc in the browser.
$fileName = 'file.pdf';
$data = file_get_contents($filePathOnDisk);
header("Content-type: application/pdf");
header("Content-disposition: attachment;filename=$fileName");
echo $data;
See PHP: stream remote pdf to client browser and Proper MIME media type for PDF files for reference as well.
Tested
You can use the following which will prompt the user to save the (PDF) file on their computer.
Notice the different file names.
One is the file that will be uploaded/prompted to the user download_example.pdf, while the other is the file without an extension as set in readfile('example');
<?php
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="download_example.pdf"');
readfile('example');
?>
I have a simple form that, when posted back, calls a function to initiate a download. The path and file name are pulled from the database then I'm using headers to start the download. My code for the download is:
//START DOWNLOAD
header('Content-type: "application/octet-stream"');
header('Content-Disposition: attachment; filename="'.$FILE_PATH.$FILE_NAME.'"');
header("Content-Transfer-Encoding: binary");
header("Connection: close")
In the example above, the $FILE_PATH variable is /downloads/software/ and the $FILE_NAME variable is client-installer.exe. So, what I would expect is a file called client-installer.exe (approximately 70MB) to be downloaded to the client. Instead, I get a file called _downloads_software_client-installer.exe and approximately 10KB.
I thought maybe I needed to urlencode the file path/name but that didn't fix the issue either. So I'm left thinking perhaps I have something wrong with the header but can't seem to find it.
Thank you!
The filename header just denotes what the file should be called. It must contain only a filename, not a path. The internal path on the server's hard disk is irrelevant and of no interest to the client. Your server will have to output the actual file data in the response, the client can't take it from the server given the path.
See readfile.