Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: Скрипт загрузки больших файлов с возможностью докачки

Сообщения:  [1-10]   [11-13] 

 
 автор: LuntiK   (07.09.2007 в 15:02)   письмо автору
 
   для: Trianon   (07.09.2007 в 14:58)
 

Огромное спасибо за подсказку, буду юзать

   
 
 автор: Trianon   (07.09.2007 в 14:58)   письмо автору
 
   для: Trianon   (07.09.2007 в 14:40)
 

Кроме того, Вам понадобится вызов

   curl_setopt($r, CURLOPT_RANGE, "дескриптор-диапазона");


и вероятно, отдельный запрос метода HEAD.

   
 
 автор: Trianon   (07.09.2007 в 14:40)   письмо автору
 
   для: LuntiK   (07.09.2007 в 14:34)
 

> $filename="http://сервер где лежит скрипт/dwl_file.php?id=1"
> $info = get_headers($filename,1);
> $f=fopen($filename, 'rb');

Извините, но get_headers, fopen - это не клиент.
Тем более - не клиент, который поддерживает докачку.
Вы в него никакой Ranges: не просунете.

Еще раз говорю, смотрите в сторону cURL.
Для затравки -

function get_url($url)
{
   $r = curl_init();
//   curl_setopt($r, CURLOPT_VERBOSE, 1);
   curl_setopt($r, CURLOPT_HEADER, 1);
   curl_setopt($r, CURLOPT_NOPROGRESS, 0);
   curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($r, CURLOPT_URL, $url);

   $res = curl_exec($r);
   return $res;
}

   
 
 автор: LuntiK   (07.09.2007 в 14:34)   письмо автору
 
   для: Trianon   (07.09.2007 в 14:20)
 

по порядку:

1. с сайта я обращаюсь к ссылке для скачивания СКАЧАТЬ, она передает параметры файла скрипту dwl.php?id=1.
2. в файле dwl.php выполняется скрипт:

    $filename="http://сервер где лежит скрипт/dwl_file.php?id=1"
    $info = get_headers($filename,1);

    $from=$to=0; $cr=NULL;
    if (isset($_SERVER['HTTP_RANGE'])) {$range=substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=')+1);
    $from=strtok($range, '-');$to=strtok('/');
    if ($to>0) $to++;
    if ($to) $to-=$from;header('HTTP/1.1 206 Partial Content');
    $cr='Content-Range: bytes ' . $from . '-' . (($to)?($to . '/' . $to+1):$info['Content-Length']);
    } else header('HTTP/1.1 200 Ok');
    $etag=md5($filename);
    $etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
    header('ETag: "' . $etag . '"');
    header('Accept-Ranges: bytes');
    header('Content-Length: ' . ($info['Content-Length']-$to+$from));
    if ($cr) header($cr);
    header('Connection: close');
    header('Content-Type: ' . $info['Content-Type']);
    header('Last-Modified: ' . $info['Last-Modified']);
    $f=fopen($filename, 'rb');
    header('Content-Disposition: '.$info['Content-Disposition']);
    if ($from) fseek($f, $from, SEEK_SET);
    if (!isset($to) or empty($to)) {$size=$info['Content-Length']-$from;
    }    else {$size=$to;}

    $downloaded = 0;
    while( (!feof($f)) && (connection_status()==0) && ($downloaded < $size) ) {

    $block = min(1024*8, $size - $downloaded);
    print(fread($f, $block));
    $downloaded += $block;
    flush();
    }

    fclose($f);
    exit;


3.скрипт dwl_file.php принимает параметры файла и отдает файл:


    $filename = "downloads/".id_file(id); //получаем имя файла с MySQL
                     if (!file_exists($filename)) die('Файл не найден');
    $from=$to=0; $cr=NULL;
    if (isset($_SERVER['HTTP_RANGE'])) {$range=substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=')+1);
    $from=strtok($range, '-');$to=strtok('/');
    if ($to>0) $to++;
    if ($to) $to-=$from;header('HTTP/1.1 206 Partial Content');
    $cr='Content-Range: bytes ' . $from . '-' . (($to)?($to . '/' . $to+1):filesize($filename));
    } else header('HTTP/1.1 200 Ok');
    $etag=md5($filename);
    $etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
    header('ETag: "' . $etag . '"');
    header('Accept-Ranges: bytes');
    header('Content-Length: ' . (filesize($filename)-$to+$from));
    if ($cr) header($cr);
    header('Connection: close');
    header('Content-Type: ' . $mimetype);
    header('Last-Modified: ' . gmdate('r', filemtime($filename)));
    $f=fopen($filename, 'r');
    header('Content-Disposition: attachment; filename="' . basename($filename) . '";');
    if ($from) fseek($f, $from, SEEK_SET);
    if (!isset($to) or empty($to)) {$size=filesize($filename)-$from;
    }    else {$size=$to;
    }

    $downloaded = 0;
    while( (!feof($f)) && (connection_status()==0) && ($downloaded < $size) ) {

    $block = min(1024*8, $size - $downloaded);
    print(fread($f, $block));
    $downloaded += $block;
    flush();
    }

    fclose($f);
    exit;


4. Если я пробую скачать файл напрямую с сервера любым брузером или загрузчиком, все ок. А вот если с сайта через первый скрипт, то получаю только начало файла, размер которого определен в первом скрипе, тоесть первый скрипт не получает заголовка о продолжении загрузки и начинает отдавать файл каждый раз сначала.

   
 
 автор: Trianon   (07.09.2007 в 14:20)   письмо автору
 
   для: LuntiK   (07.09.2007 в 14:08)
 

А я вообще ничего не понял.
Давайте еще раз и поточне:
1. Обращаюсь с клиентского компьютера С0 к контенту на сервере S1.
2. В IE (или flashget) компьютера C0 набираю адрес
http://s1/script1.php?name=....


3. файл //s1/script1.php выглядит следующим образом:
....код....

4. файл //s1/script1.php обращается обращается в строке ... к файлу script2 на сервере S2
5. файл //s2/script2.php выглядит следующим образом:
....код....

6.Вместо ожидаемого того-то и того-то
....

7.происходит то-то и то-то
....


PS. Код, действительно, лучше помещать в псевдотеги.[cоde]код[/cоde]

   
 
 автор: LuntiK   (07.09.2007 в 14:08)   письмо автору
 
   для: Trianon   (07.09.2007 в 13:59)
 

не совсем понял про клиентскую

ссылка выдается вида <a href="dwl.php?id=1&key=123">скачать</a>
файл dwl.php содержит второй скрипт.
и тоже передает полученные параметры первому скрипту на другом сервере.

скачать пробую flashget и IE

   
 
 автор: Trianon   (07.09.2007 в 13:59)   письмо автору
 
   для: LuntiK   (07.09.2007 в 13:40)
 

это всё скрипты серверной стороны.
Я спрашиваю про клиентскую.

   
 
 автор: bronenos   (07.09.2007 в 13:58)   письмо автору
 
   для: LuntiK   (07.09.2007 в 13:40)
 

обрамите в [ code ]

   
 
 автор: LuntiK   (07.09.2007 в 13:40)   письмо автору
 
   для: Trianon   (07.09.2007 в 13:36)
 

первый скрипт:
$filename = "файл на сервере";
if (!file_exists($filename)) die('Файл не найден');
$from=$to=0; $cr=NULL;
if (isset($_SERVER['HTTP_RANGE'])) {$range=substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=')+1);
$from=strtok($range, '-');$to=strtok('/');
if ($to>0) $to++;
if ($to) $to-=$from;header('HTTP/1.1 206 Partial Content');
$cr='Content-Range: bytes ' . $from . '-' . (($to)?($to . '/' . $to+1):filesize($filename));
} else header('HTTP/1.1 200 Ok');
$etag=md5($filename);
$etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
header('ETag: "' . $etag . '"');
header('Accept-Ranges: bytes');
header('Content-Length: ' . (filesize($filename)-$to+$from));
if ($cr) header($cr);
header('Connection: close');
header('Content-Type: ' . $mimetype);
header('Last-Modified: ' . gmdate('r', filemtime($filename)));
$f=fopen($filename, 'r');
header('Content-Disposition: attachment; filename="' . basename($filename) . '";');
if ($from) fseek($f, $from, SEEK_SET);
if (!isset($to) or empty($to)) {$size=filesize($filename)-$from;
} else {$size=$to;
}

$downloaded = 0;
while( (!feof($f)) && (connection_status()==0) && ($downloaded < $size) ) {

$block = min(1024*8, $size - $downloaded);
print(fread($f, $block));
$downloaded += $block;
flush();
}

fclose($f);
exit;

Второй:

$filename = "URL к файлу"
$info = get_headers($filename,1);

$from=$to=0; $cr=NULL;
if (isset($_SERVER['HTTP_RANGE'])) {$range=substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=')+1);
$from=strtok($range, '-');$to=strtok('/');
if ($to>0) $to++;
if ($to) $to-=$from;header('HTTP/1.1 206 Partial Content');
$cr='Content-Range: bytes ' . $from . '-' . (($to)?($to . '/' . $to+1):$info['Content-Length']);
} else header('HTTP/1.1 200 Ok');
$etag=md5($filename);
$etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
header('ETag: "' . $etag . '"');
header('Accept-Ranges: bytes');
header('Content-Length: ' . ($info['Content-Length']-$to+$from));
if ($cr) header($cr);
header('Connection: close');
header('Content-Type: ' . $info['Content-Type']);
header('Last-Modified: ' . $info['Last-Modified']);
$f=fopen($filename, 'rb');
header('Content-Disposition: '.$info['Content-Disposition']);
if ($from) fseek($f, $from, SEEK_SET);
if (!isset($to) or empty($to)) {$size=$info['Content-Length']-$from;
} else {$size=$to;}

$downloaded = 0;
while( (!feof($f)) && (connection_status()==0) && ($downloaded < $size) ) {

$block = min(1024*8, $size - $downloaded);
print(fread($f, $block));
$downloaded += $block;
flush();
}

fclose($f);
exit;

   
 
 автор: Trianon   (07.09.2007 в 13:36)   письмо автору
 
   для: LuntiK   (07.09.2007 в 13:31)
 

Чем Вы пользуетесь в качестве http-клиента?
Я советую применять cURL-вызовы.

   

Сообщения:  [1-10]   [11-13] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования