You can use a bit of code like the following example to check to see whether they're logged in to a valid session and then download the file from outside the web root.
Code:
<?php
session_start();
if ($SESSION_USERID) {
$browser = $_SERVER["HTTP_USER_AGENT"];
if (preg_match('/MSIE 5.5/', $browser) || preg_match('/MSIE 6.0/', $browser)) {
header('Content-Disposition: filename="myfile.zip"');
} else {
header('Content-Disposition: attachment; filename="myfile.zip"');
}
header('Content-Transfer-Encoding: binary');
header("Content-type: application/octet-stream");
header('Pragma: no-cache');
header('Expires: 0');
readfile("../protected/myfile.zip");
} else {
header("Location: ./");
}
?>
This bit has been tested with zip files in IE and firefox. You may have to mess with the headers a bit for other browsers / filetypes.