File size: 4.06Kb
<?php
/**
* Отдача файла скриптом с поддержкой докачки. Используется для работы счетчиков скачиваний.
*/
class download {
public $path;
public $name;
public $mime = 'application/octet-stream';
/**
*
* @param string $name Название файла для отображения в браузере
* @param string $path Абсолютный путь к файлу на сервере
*/
function __construct($name, $path) {
$this->path = $path;
$this->name = $name;
}
/**
* Существует ли agqk на сервере
* @return bool
*/
function exists() {
return is_file($this->path);
}
/**
* Отправляет запрошенное содержимое в браузер
* @return int кол-во отправленных байт
*/
function output() {
$this->mime = $this->get_mime();
@ob_end_clean();
$from = 0;
$to = $size = filesize($this->path);
if (isset($_SERVER['HTTP_RANGE'])) {
if (preg_match('#bytes=-([0-9]+)#i', $_SERVER['HTTP_RANGE'], $range)) { // если указан отрезок от конца файла
$from = $size - $range[1]; // начало файла
$to = $size; // конец файла
} elseif (preg_match('#bytes=([0-9]+)-#i', $_SERVER['HTTP_RANGE'], $range)) { // если указана только начальная метка
$from = $range[1]; // начало
$to = $size; // конец
} elseif (preg_match('#bytes=([0-9]+)-([0-9]+)#i', $_SERVER['HTTP_RANGE'], $range)) { // если указан отрезок файла
$from = $range[1]; // начало
$to = $range[2]; // конец
}
header('HTTP/1.1 206 Partial Content');
$cr = 'Content-Range: bytes ' . $from . '-' . $to . '/' . $size;
} else {
header('HTTP/1.1 200 Ok');
}
$etag = md5($this->path);
$etag = substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
header('ETag: "' . $etag . '"');
header('Accept-Ranges: bytes');
header('Content-Length: ' . ($to - $from));
if (isset($cr)) {
header($cr);
}
header('Connection: close');
header('Content-Type: ' . $this->mime);
header('Last-Modified: ' . gmdate('r', filemtime($this->path)));
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($this->path)) . ' GMT');
header('Expires: ' . gmdate('D, d M Y H:i:s', TIME + 3600) . ' GMT');
$f = fopen($this->path, 'rb');
if (!preg_match('#^image/#i', $this->mime)) {
// если файл не является изображением, то его отображать в браузере не нужно
header('Content-Disposition: attachment; filename=' . convert::of_utf8(basename($this->name)));
}
if (@function_exists('ini_set')) {
// при использовании встроенного сжатия возникали проблемы со скачиванием файлов
ini_set('zlib.output_compression', 'Off');
}
fseek($f, $from, SEEK_SET);
$size = $to;
$downloaded = 0;
while (!feof($f) and !connection_status() and ($downloaded < $size)) {
$block = min(1024 * 8, $size - $downloaded);
echo fread($f, $block);
$downloaded += $block;
flush();
}
fclose($f);
return $downloaded; // возвращаем кол-во скачаных байт
}
/**
* получение mime-типа файла по расширению
* @return string
*/
function get_mime() {
return files_types::get_mime($this->name);
}
}
?>