Multiple downloads.
Well, I have officially become stuck. Is it possible to download more than one file at a time with PHP headers? I have even tried incorporating JavaScript to detect the page loading completion with no luck.
if(ini_get('zlib.output_compression')){ini_set('zlib.output_compression', 'Off');}
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"" . $filename . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ". filesize($filename));
readfile("$filename");
[593 byte] By [
PeejAvery] at [2007-11-19 22:59:55]

# 1 Re: Multiple downloads.
Errmmm...sounds interesting...have you tried writing a tree traversal part before you execute the header part?
Something like this...i can't try coding yet as i'm tied with something now...
The concept is something like this
<?php
// A While loop doing a tree traversal.
if ( $handle = @opendir('.') ) {
while ( false != ($file = @readdir($handle)) ) {
// Get all the file's names.
// then do you downloading from here.
}
}
?>
What i'm not sure of is whether it will continue to download after downloading the first file found. I didn't do this before either... :blush:
But i think there is a limitation for users using IE as the maximum download from per website is 2 unless you do a tweak to the PC's registry.
Sorry i can't help you much for the downloading part but i can help with the tweak on registry if you need to do so. :p
e_har at 2007-11-10 3:57:20 >

# 2 Re: Multiple downloads.
You cannot use a loop because the one download header stops all future headers. The code I posted is for one download. Any code after the readfile() will not fire.
# 3 Re: Multiple downloads.
Hey Guys,
I'm having a vaguely similar problem and I was wondering if anybody knew of a solution or could tell me what's going on...
I have a page where there are multiple files the user need to download. Each of the file links goes to a PHP page which has a GET parameter passed to it. The parameter is then used to identify the file to download. It reads out a file from outside the webroot and forces it to download. That's working great, however there is one problem. Once the user clicks one link the file starts to download, however if they try to click another download link while the first file is still transferring it doesn't start to download until the first file has finished.
Is it not possible for PHP to serve multiple files at once? Just to be clear I'm not trying to have one processed page serve multiple files, but have the same page be hit multiple times each time serving out a different file.
I'd really appreciate any thoughts you guys had as this is really got me stumped and I'm having a devil of a time trying to get anything out of google on this issue.
OK clearly something much broader is going on as it's not just the other files that can't be download, but no other PHP page will be served until the file download has completed. Can something be wrong with my PHP configuration or is it likely to be my file download that's doing something evil?
I guess some code might help, here's the bit that does the download:
header("HTTP/1.1 200 OK");
header("Content-Length: $fsize");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"$nicename\";");
header("Content-Transfer-Encoding: binary");
if(file_exists($fpath) && $fh = fopen($fpath, "rb")){
while($buf = fread($fh, $bufsize)) {
print $buf;
fclose($fh);
}
} else {
header("HTTP/1.1 404 Not Found");
}
# 4 Re: Multiple downloads.
@PixelNurse: As I stated, once the final header for the download is set, PHP automatically exits. That is why you cannot download multiples.
What I did, and I don't like it, is made it sort the filenames from the array and echo a whole frameset. Each frame shoots to a different file to be downloaded. The only problem is that it is limited by the browser to the default maximum number of downloads.
# 5 Re: Multiple downloads.
@PixelNurse: As I stated, once the final header for the download is set, PHP automatically exits. That is why you cannot download multiples.
What I did, and I don't like it, is made it sort the filenames from the array and echo a whole frameset. Each frame shoots to a different file to be downloaded. The only problem is that it is limited by the browser to the default maximum number of downloads.
Yeah I know, I'm not trying to get one load of the php page to download multiple files. I'm trying to hit the page multiple times, each time passing a different var and triggering a different file.
I don't think we're having the same problem, it just seemed logical to add to this thread a sit was kinda related and I thought it an area of common expertise.
# 6 Re: Multiple downloads.
Yeah I know, I'm not trying to get one load of the php page to download multiple files. I'm trying to hit the page multiple times, each time passing a different var and triggering a different file.
Exactly. I have tried this too. As I said, since the headers are sent, that PHP page is now dead. There is no way to send any data to be able to know when to send the next variable. I have tried this also.
I don't think we're having the same problem, it just seemed logical to add to this thread a sit was kinda related and I thought it an area of common expertise.
Yes, we are having the same exact problem. It is just that we are trying different solutions at the moment. I have exhausted all that I know.
# 7 Re: Multiple downloads.
Exactly. I have tried this too. As I said, since the headers are sent, that PHP page is now dead. There is no way to send any data to be able to know when to send the next variable. I have tried this also.
Yes, we are having the same exact problem. It is just that we are trying different solutions at the moment. I have exhausted all that I know.
So you're saying that until the page, let's call it download.php has finished shunting out the file, I can't call download.php again? So this means that any php page that takes a long time to complete can't be accessed by another user while the first user is still accessing it?
That would mean that while I'm loading say this very forum page, not other user could load it until it's stopped?
Just so I'm 100% sure that you're saying this is impossible:
links.php
|
|-->html href link to download.php?file_id=1
|-->html href link to download.php?file_id=2
|-->html href link to download.php?file_id=3
This is impossible? I have to wait for "download.php?file_id=1" to complete parsing before I can access "download.php?file_id=2"? And not only that but no other PHP file anywhere on the server can be parsed either? Because that's what I'm experiencing right now.
I thought from what you'd written that you wanted to have one php page hit once, and sequentially force multiple files out to the browser.
# 8 Re: Multiple downloads.
No. Sorry. I guess I was not clear.
What I am saying is...whatever window you load your download script into, it is dead to PHP. JavaScript can work with it from a different window but that window is dead. That is due to the headers.
You can use JavaScript to send it to one link after the other, but if the server times out, only PHP can determine that and JavaScript will continue without knowing that there was an error.
# 9 Re: Multiple downloads.
Hey thanks for replying you had me REALLY worried :), I was about to declare PHP a dead and amateur language. I'm not trying to do any detection or triggering with JS I realise that once it's pushed the headers there is no HTML file, that's the point of the headers. I have access to my server php.ini etc and I'm able to make sure the server doesn't time out.
I have it all working well, it updates a DB record after the file completes and everything. The one problem I'm having is whatever method i use for PHP to read and spit out the file, whether it be readfile, passthru, exec, etc, seems to be tying up PHP completely. I can access no other PHP files until it has finished sending the downloading file.
The server has nothing else running on it, it's colo'd through a gigabit switch, has big fat pipe to the net, etc.
It's bloody weird huh?
# 10 Re: Multiple downloads.
@PixelNurse:
I couldn't understand what you are trying to do here.
1.) You want a single php script that enables you to download multiple files at one try?
2.) You want a single php script that enables you to surf other pages even if you have just downloaded several files.
If it's option 1, i think PeeJavery has explained it quite well.
But if it's option 2, that's too simple
Here is a simple script if you're referring to option 2.
index.php
|
|-->html href link to dl.php?file=1
|-->html href link to dl.php?file=2
|-->html href link to dl.php?file=3
<?php
// index.php
echo '<html><head><title>Multiple Downloads</title></head><body>';
echo '<a href="dl.php?file=1">1</a><br>';
echo '<a href="dl.php?file=2">2</a>';
echo '</body></html>';
?>
<?php
// dl.php
$fname = $_GET['file'];
$fsize = filesize($fpath);
$bufsize = 20000;
$fpath = <Get the location of the file from your database>
$file_ext = strtolower(substr(strrchr($fname, "."), 1));
// Switch statement to determine how they should be be opened.
switch($file_ext) {
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream";
case "exe": $ctype="application/octet-stream";
case "exe": $ctype="application/octet-stream";
case "exe": $ctype="application/octet-stream";
case "exe": $ctype="application/octet-stream";
// You can add you own...this is only a example.
default: $ctype="application/force-download";
}
// Begin to write the headers.
header("Pragma: no-cache");
header("Expires:0");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-checck=0", false);
header("Content-Description: File Transfer");
// Use the $ctype to declare the content type.
header("Content-Type: " . $ctype);
$file_space = str_replace(" ", ".", $fname);
// Force the download.
if(file_exists($fpath) && $fh = fopen($fpath, "rb")) {
while(!feof($fh) && (connection_status() == 0)) {
print(fread($fh, 1024*8));
flush();
}
fclose($fh);
}
return((connection_status()==0 && !connection_aborted());
}
?>
Another to take note is the the limit of downloads from per site is 2 for IE 6 and below unless you tweak the registry. I hope that it's all clear now.
e_har at 2007-11-10 4:06:29 >

# 11 Re: Multiple downloads.
Any luck on a solution PixelNurse? I'm having the EXACT same issue as you. I have a page, download.php ironically, that takes a get variable of the track id and then forces the user to download the file corresponding to that id. Unfortunately once they click and begin a download they can not click and begin another download. It would be nice to have them load all of the desired files into firefox's download manager but they must wait for the first track to finish before being prompted to save the next one.
I ran an experiment to see if perhaps its the file (download.php) that is being "
tied" up so if there was another file (download1.php) then I could download 2 files. This didn't work fortunately as I wouldn't want to have n download files to serve n requests.
There must be a way to do this...
# 12 Re: Multiple downloads.
Unfortunately, neither of us were able to accomplish this.
# 13 Re: Multiple downloads.
Bingo! I solved it (at least in my case). The kicker? Sessions.
My download.php file was calling session_start() at the top and wouldn't allow that same page to start another session until the previous one had exited. I just removed the call to session_start at the top (albeit at losing my session variables which I switched to GET variables) and I can now download multiple files through the same page at once.
Hopefully that will help you guys as well.
- Mr. Kickass
edit: The GET thing didn't work so I just pulled out the stuff that needed the session variables in one page and then used "header("Location: real_download.php?...") to do the actual forced header download stuff.