I'm trying to send a zip file to the user.
$file_info = get_file_info($filepath_name);
header("Content-Type: " . get_mime_by_extension($filepath_name));
header("Content-Length: " . $file_info["size"]);
header_remove('Pragma');
header_remove('Cache-Control');
//header("Content-Type: application/force-download");
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.urlencode($filepath_name));
header('Location: file://'.$filepath_name);
readfile($filepath_name);
$filepath_name
is set to "D:\dev2.local\storage_users\1\export_data\course_2357.zip".
readfile()
returns the correct size of file but the file is still not served for downloading.
I've tried all the combinations of headers settings to no avail.
Problem found:
This functionality was called via AJAX call, thats why php didnt allow file to be send.
Solution found: Had to return file path and name back to js from where php was ajaxed and serve file from js.
EDIT: this is the workaround I used:
var hostname = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
jQuery('<iframe>', {
src: hostname + value.return_zip,
id: 'iFrame_zip_download',
frameborder: 0,
scrolling: 'no'
}).appendTo('#export_import_status');
Where value.return_zip is relative path to file on server (/storage_users/xx/xx/xx.zip). I then add hostname and it turns out nicely for example: https://www.google.com/storage_users/xx/xx/xx.zip. iFrame is hidden in status div.
Looks like there's some problem with your header.
You could try something like this:
ob_start();
//OR
ob_clean();
header("Content-Type: " . get_mime_by_extension($filepath_name));
/* Other code */
I don´t know if that is the order you are typing, but: have you tried putting:
$filepath_name = "D:\\dev2.local\\storage_users\\1\\export_data\\course_2357.zip"
on the top of the code, or at least before the readfile()
Waiting for your update.
header('Location: file://'.$filepath_name);
looks problematic. This is a special use of the header
function which sends a 302 Redirect HTTP status to the browser, redirecting to the URL specified.
It's not adding anything here, I'd remove it.
The correct MIME type for ZIP archives is application/zip
not application/octet-stream
. Sending the correct header makes it more likely the browser will open the file in the correct program.
URL-encoding the full path to the file results in a filename that's 69 characters long. I think it's unlikely this is long enough to be causing a problem, but we might as well simplify it by just sending the basename "course_2357.zip". I don't think URL-encoding the filename is necessary at all - this seems to stem from an Internet Explorer 8 hack to get UTF-8 characters working which isn't required in your case - but I've left it in place as it isn't doing any harm.
I've used PHP's built-in filesize
rather than get_file_info
because I don't have CodeIgniter installed. I assume this is where this function comes from?
The following code based on what you've provided above works for me:
header("Content-Length: " . filesize($filepath_name));
header_remove('Pragma');
header_remove('Cache-Control');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename='.urlencode(basename($filepath_name)));
readfile($filepath_name);