Иногда бывает полезным не сохранять кучу файлов на каком-либо хостинге, а использовать только один архивный файл. Но возникает проблема доступа к конкретному файлу в архиве. Предлагаю вашему вниманию PHP скрипт, который позволяет загружать часть архивного файла как целый файл. Поддерживается дозагрузка через запросы RANGE. Архив, в данном случае, просто склейка из множества файлов. В настоящий момент скрипт протестирован с менеджером загрузок Flashget.
Для того, чтобы загрузить конкретный файл достаточно указать его смещение в архивном файле, размер и имя этого файла следующим образом:
htp://адрес/имя_скрипта.php?name=filename&offset=3000&size=100
В результате пользователь такой ссылки получит файл размером 100 байт с именем filename, который находится по смещению 3000 архивного файла.
Для того, чтобы загрузить конкретный файл достаточно указать его смещение в архивном файле, размер и имя этого файла следующим образом:
htp://адрес/имя_скрипта.php?name=filename&offset=3000&size=100
В результате пользователь такой ссылки получит файл размером 100 байт с именем filename, который находится по смещению 3000 архивного файла.
Copy Source | Copy HTML
- <?php
- $offset = isset($_REQUEST['offset']) ? (int) $_REQUEST['offset'] : 0;
- $size = isset($_REQUEST['size']) ? (int) $_REQUEST['size'] : false;
- $name = isset($_REQUEST['name']) ? urlencode($_REQUEST['name']) : 'download.bin';
-
- if (empty($size)) die;
-
- // link to archive file
- $url = 'http://archive_file_url';
-
- @set_time_limit(0);
-
- $range_size = $size;
- $range_offset = $offset;
-
- if (isset($_SERVER['HTTP_RANGE'])) {
- if (preg_match('/^bytes=(\d+)\-$/', $_SERVER['HTTP_RANGE'], $m)) {
- $range_offset+=$m[1];
- $range_size-=$m[1];
- } elseif (preg_match('/^bytes=(\d+)\-(\d+)$/',$_SERVER['HTTP_RANGE'], $m)) {
- $range_offset+=$m[1];
- $range_size=$m[2]-$m[1]+1;
- } else {
- // TODO (aig): support other ranges if needed
- die();
- }
- header('HTTP/1.1 206 Partial Content');
- } else {
- header('HTTP/1.1 200 Ok');
- }
-
- $range = ($range_offset)."-".($range_offset+$range_size-1);
- header("Content-Type: application/octet-stream");
- header("Accept-Ranges: bytes");
- header("Content-Length: $range_size");
- header('Content-Disposition: attachment; filename="' . $name . '";');
-
- $ch = curl_init();
- curl_setopt($ch,CURLOPT_URL,$url);
- curl_setopt($ch,CURLOPT_RANGE,$range);
- curl_setopt($ch,CURLOPT_RETURNTRANSFER,0);
- curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
- curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3');
- curl_exec($ch);
- curl_close($ch);
- ?>
-