Здесь рассмотрим различные варианты отправки файла пользователю "на лету". Т.е. пользователь не сам забирает лежащий на вашем сервере файл, а мы отдаем пользователю файл с помощью PHP-скрипта. Простейший пример отправки файла с формированием полного заголовка выглядит так:
Header("HTTP/1.1 200 OK");
Header("Connection: close");
Header("Content-Type: application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Content-Disposition: Attachment; filename=filename.dat");
Header("Content-Length: 50000");
readfile('MyFile.dat');Здесь функция readfile читает файл и записывает его в буфер вывода.
Рассмотрим более сложный вариант скрипта с ограничением скорости скачивания:
$fname=$_GET['fname'];
$fsize=filesize('secret_data/'.$fname);
Header("HTTP/1.1 200 OK");
Header("Connection: close");
Header("Content-Type: application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Content-Disposition: Attachment; filename=".$fname);
Header("Content-Length: ".$fsize);
// Открыть файл для чтения и отдавать его частями
$f=fopen('secret_data/'.$fname,'r');
while (!feof($f)) {
// Если соединение оборвано, то остановить скрипт
if (connection_aborted()) {
fclose($f);
break;
}
echo fread($f,10000);
// Пазуа в 1 секунду. Скорость отдачи 10000 байт/сек
sleep(1);
}
fclose($f);Вариант скрипта скрипта для скачивания файла с поддержкой докачки:
$fname=$_GET['fname'];
$fsize=filesize('secret_data/'.$fname);
$fdown='secret_data/'.$fname;
// Установлена или нет переменная HTTP_RANGE
if (@getenv('HTTP_RANGE')=="") {
// Читать и отдавать файл от самого начала
$f=fopen($fdown, 'r');
header("HTTP/1.1 200 OK");
header("Connection: close");
header("Content-Type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Content-Disposition: Attachment; filename=".$fname);
header("Content-Length: ".$fsize);
while (!feof($f)) {
if (connection_aborted()) {
fclose($f);
break;
}
echo fread($f, 10000);
sleep(1);
}
fclose($f);
}
else {
// Получить значение переменной HTTP_RANGE
preg_match ("/bytes=(\d+)-/", getenv('HTTP_RANGE'), $m);
$csize=$fsize-$m[1]; // Размер фрагмента
$p1=$fsize-$csize; // Позиция, с которой начинать чтение файла
$p2=$fsize-1; // Конец фрагмента
// Установить позицию чтения в файле
$f=fopen($fdown, 'r');
fseek ($f, $p1);
header("HTTP/1.1 206 Partial Content");
header("Connection: close");
header("Content-Type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Content-Disposition: Attachment; filename=".$fname);
header("Content-Range: bytes ".$p1."-".$p2."/".$fsize);
header("Content-Length: ".$csize);
while (!feof($f)) {
if (connection_aborted()) {
fclose($f);
break;
}
echo fread($f, 10000);
sleep(1);
}
fclose($f);
}C учетом ососбенностей браузеров:
function send_download($data, $filename)
{
header("HTTP/1.1 200 OK");
header("Content-Type: application/force-download; charset=utf-8");
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
$ua = (isset($_SERVER['HTTP_USER_AGENT']))?$_SERVER['HTTP_USER_AGENT']:'';
$isMSIE = preg_match('@MSIE ([0-9].[0-9]{1,2})@', $ua);
if ($isMSIE)
{
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
}
else
{
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Pragma: no-cache');
}
echo $data;
}
Комментарии:
Пока нет комментариев.
Чтобы оставить комментарий, войдите.