Website becomes unusable while downloading file served by PHP script - php

I'm running IIS 8.0 and have a script that serves various downloads when someone clicks on a download link. However I'm running into an issue where as long as a user is downloading something the website is completely unresponsive until that download completes. Below is the code for the download script. This script is being opened in a new window.
$extension = fileexten($filename);
if(($filename!= false)&&($fakename!=false&& #fopen($filename,'r')==true)){
$mime = contenttype($extension);
set_time_limit(0);
header('Pragma: public');
header('Expires: 0');
header("Content-Type:".$mime);
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Disposition: attachment;filename='.$fakename.'.'.$extension);
header("Content-Transfer-Encoding: binary");
if (ob_get_length() > 0) {
ob_end_clean();
}
flush();
readfile($filename);
}
else{
$error = "<h3>We could not find this file</h3>";} // If the filename or fake filename could not be retrieved.
}

Close the session before outputting the file.
session_write_close();
readfile($filename);
The session can only be opened by one PHP process at a time, and any other requests that issue a session_start() command will block while waiting for access to the session data file.

Related

PHP download script, downloads automatically instead of prompting as it should

I have a script that starts a download in PHP. When users click on the link that starts the download it should prompt the user whether they want to save the file or not. It works fine in firefox, but in Safari and Chrome the download starts automatically without prompting the user.
Here is my code
$extension = fileexten($filename);
if(($filename!= false)&&($fakename!=false&& #fopen($filename,'r')==true)){
$mime = contenttype($extension);
set_time_limit(0);
header('Pragma: public');
header('Expires: 0');
header("Content-Type:".$mime);
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Disposition: attachment;filename='.$fakename.'.'.$extension);
header("Content-Transfer-Encoding: binary");
if (ob_get_length() > 0) {
ob_end_clean();
}
flush();
readfile($filename);
}
else{
$error = "<h3>We could not find this file</h3>";} // If the filename or fake filename could not be retrieved.
}
Is there anyway I can make sure the browser prompts them to save or download the file rather than it start automatically in other browsers?
It has nothing to do with a script but a browser setting.
In case of Google Chrome that's how you change it:

ios shows file in mobile safari rather than downloading?

I am using the following code to present a file for download to the user... in this case it is a .csv file. Works great in all browsers, BUT in IOS it loads the file in the mobile safari browser. The exact same code works fine for a .zip file (although ios gives the warning it cannot download that type of file).
What gives? Does ios completely disregard the headers or what?
if (is_file($local_path.$file))
{
//get current ts
$now = time();
// set the headers and prevent caching
header('Pragma: public');
header('Expires: -1');
header('Cache-Control: public, must-revalidate, post-check=0, pre-check=0');
header('Content-Disposition: attachment; filename="'.$now.'_'.$file.'"');
// set the mime type based on extension
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_path.$file).'');
//download
readfile($local_path.$file);
//delete file
unlink($local_path.$file);
}

PHP force downloading

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.

PHP force download of remote file without reading into memory

Is it possible to force a download of remote file in PHP without reading it into memory? I know fpassthru(), readfile(), file_get_contents() all reads the files into memory before outputting it into the browser.
Here's my code:
if($url = getRemoteFileURL($file_id))
{
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="abc.zip"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Pragma: no-cache');
readfile($url); // is there a better function ?
}
I don't want to do header("Location: ") because that would reveal the URL
If you do a header("Location: ..."); to a downloaded file, the URL isn't actually revealed much, if at all.
Anyway, readfile is probably your best option. I would assume, given that it writes straight to the output, that PHP proceeds by reading in a part of the file, then outputting it, then reading the next part, etc., overall using very little memory.

PHP Downloading File(s) outside webroot

I save many documents outside the webroot.
I want to click a link, that opens a new window (target="_blank"), and force download the file that's found.
Here's what I've got so far, but my results show gobble-de-gook in the browser popup, rather than forcing the download to the desktop:
function download($filelocation){
$filename = basename($filelocation);
if (file_exists($filelocation)) {
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($filelocation));
ob_clean();
flush();
readfile($filelocation);
exit;
}
}
In the new browser window I simply call that download() function with a specific path the the file.
It's definitely finding the file, but now I'm just wondering what I'm missing with header() to force the file through the browser.
Missing this:
header("Content-Type: application/force-download");

Categories