Karayazi » 2013.04.12 11:50

Здравствуйте, вот скрипт который закачивает удалённый файл на сервер а потом отдает пользователю.

Код:

1
span style="color: #0000BB"><?phpinclude 'head.php';include 'config.php';$file = trim(base64_decode($_GET['file']));$ext = $_GET['ext'];$size = get_size($file);$name = trim($_GET['name']);$rand = rand(0, 10);echo '<div class="title">Скачивание файла</div>';echo '<div class="main_menu">Название: '.$name.'<br/>Формат: '.$ext.'<br/>Размер: '.sizeformat($size).'</div>';$newfile = 'files/'.$name.'('.$_SERVER['HTTP_HOST'].').'.$ext;if(filesize($newfile)==$size) {echo '<div class="main_menu">Файл готов:<br/> <a href="'.$newfile.'"><b>Скачать</b></a> </div><div class="foot">&#171; <a href="index.php">Главная</a></div>';}elseif(file_exists($newfile) && filesize($newfile)!=$size){echo '<div class="main_menu">Готовность файла: <b> '.round(filesize($newfile)/($size/100)).'%</b><br/>Файл подготавливается к скачиванию, <a href="?file='.$_GET['file'].'&name='.$name.'&ext='.$ext.'&'.$rand.'">обновите</a> страницу через 5-10 секунд!</div>';}elseif(!file_exists($newfile)){echo '<div class="main_menu">Файл подготавливается к скачиванию, <a href="?file='.$_GET['file'].'&name='.$name.'&ext='.$ext.'&'.$rand.'">обновите</a> страницу через 5-10 секунд!</div>';ini_set('max_execution_time',600);$fp=fopen($newfile,"w");//создаем пустой файлfclose($fp);$ch=curl_init();curl_setopt($ch, CURLOPT_URL, $file);//запускаем сеанс curl$fp=fopen($newfile,"w+");//открываем файл для записиcurl_setopt($ch, CURLOPT_FILE, $fp);// записываем в файлcurl_setopt($ch, CURLOPT_REFERER, $file);curl_setopt($ch, CURLOPT_AUTOREFERER, 1);curl_exec ($ch);//выполняем команды curlcurl_close ($ch);//завершаем сеанс curlfclose ($fp);//закрываем файл}include 'foot.php';?>

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

Gemorroj » 2013.04.12 12:41

тут проще будет использовать навороченные готовые js решения.
по сути, должно быть минимум 2 скрипта - 1 отображает данные пользователю, 2 - закачивает файл.

Karayazi » 2013.04.12 13:20

А без js нельзя?
И вообще, можно ли как нибудь отдавать файл на закачку пользователя  переименовать названия налету, не перегружая его на свой сервер?
Дело в том что, сервер, откуда скачивается файл генерирует ссылку по ип моего сервера, можно как нибудь обойти это?

Gemorroj » 2013.04.12 14:46

Karayazi, думаю нет. Можно только если сильно заморачиваться, организовать что-то вроде потока. Т.е. читаем файл кусками на удаленном сервере и сразу же эти куски отдаем.

Karayazi » 2013.04.12 15:07

Gemorroj, я сделал так:

Код:

1
span style="color: #0000BB"><?phpinclude 'config.php';$file = trim(base64_decode($_GET['file']));$ext = $_GET['ext'];$size = get_size($file);$name = trim($_GET['name']);$name=$name.'('.$_SERVER['HTTP_HOST'].').'.$ext;header ("Content-Type: application/octet-stream");header ("Accept-Ranges: bytes");header ("Content-Length: ".$size);header ("Content-Disposition: attachment; filename=".$name); readfile($file);?>

И файл нормально передаётся браузеру на скачку, и скачивается нормально, но в браузере не видно разиер файла, а только размер процесса скачки, можно сделать так что бы полный размер файла тоже показывало?

Gemorroj » 2013.04.12 18:27

это тебе докачку делать надо.

Karayazi » 2013.04.13 02:34

Сделал так:

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
function output_file($file,$name, $size)
{
if (ereg('Opera(/| )([0-9].[0-9]{1,2})', $_SERVER['HTTP_USER_AGENT']))
$UserBrowser = "Opera";
elseif (ereg('MSIE ([0-9].[0-9]{1,2})', $_SERVER['HTTP_USER_AGENT']))
$UserBrowser = "IE";
else
$UserBrowser = '';
$mime_type = ($UserBrowser == 'IE' || $UserBrowser == 'Opera') ?
'application/octetstream' : 'application/octet-stream';
@ob_end_clean();
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header('Accept-Ranges: bytes');
header("Cache-control: private");
header('Pragma: private');
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE']);
str_replace($range, "-", $range);
$size2 = $size-1;
$new_length = $size-$range;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range$size2/$size");
}
else {
$size2=$size-1;
header("Content-Range: bytes 0-$size2/$size");
header("Content-Length: ".$size);
}
$chunksize = 1*(1024*1024);
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
if(isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);
while(!feof($file) and (connection_status()==0))
{
$buffer = fread($file, $chunksize);
print($buffer);
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
}
else
die('error can not open file');
if(isset($new_length))
$size = $new_length;
die();
}

Теперь нормально, но иногда скрипт очень долго думает.

Gemorroj » 2013.04.13 09:15

$mime_type = ($UserBrowser == 'IE' || $UserBrowser == 'Opera') ?
  'application/octetstream' : 'application/octet-stream';
вот это не нужно. отправляй application/octet-stream

Karayazi » 2013.04.13 18:31

Gemorroj, ок, спасибо большое.

WapStyle » 2013.04.26 22:55

без JS можно
пример с моего старого скрипта

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
case 'upload':
$db->beginTransaction();
$sql = $db->prepare('SELECT * FROM `files` WHERE `id` = ?');
$sql->execute(array($_GET['id']));
$load = $sql->fetch();
$db->commit();
 
if(empty($load[0])) die ('<div style="text-align:center;">'.$language['1005'].'</div>');
$db->beginTransaction();
$sql = $db->prepare('SELECT * FROM `error` WHERE `file` = ?');
$sql->execute(array($load[1]));
$error = $sql->fetch();
$db->commit();
if(!empty($error[0])) die ('<div style="text-align:center;">'.$error[2].'</div>');
if(!empty($load[8])){ unset($_SESSION['protect']); header('Location: /view/'.$load[0].'/'); exit(); }
$tmp = './files/tmp/'.$load[1].'.size';
define('TITLE', $language['040']);
require_once ('style/head.php');
echo '<div class="contur"><div class="header"><div style="text-align: left">';
if(empty($_GET['provkod'])){
echo '<form action="/get/upload/'.$load[0].'/" method="get"><fieldset style="border: none">';
echo '<img src="/protect.php?'.SID.'" alt="image"/> <a href="/get/upload/'.$load[0].'/">'.$language['041'].'</a><br/><input name="provkod" size="4" maxlength="4" />';
echo '<input type="submit" value="Ok" /></fieldset></form>';
} else if($_GET['provkod'] == $_SESSION['protect']){
if (!file_exists($load[6])) open('GET', '/get/auto/'.$load[0].'/');
echo '<meta http-equiv="refresh" content="10;url=/get/upload/'.$load[0].'/?provkod='.intval($_GET['provkod']).'">';
echo $language['042'].'<strong>'.procent(file_exists($load[6]) ? filesize($load[6]) : 0, file_exists($tmp) ? file_get_contents($tmp) : 1) . '%</strong><br />';
echo $language['043'].'<a href="/get/upload/'.$load[0].'/?provkod='.intval($_GET['provkod']).'&amp;'.rand(0, 10).'">'.$language['044'].'</a><br/>';
echo $language['045'];
} else {
echo '<div style="color:red">'.$language['1007'].'</div>';
echo '<a href="/get/upload/'.$load[0].'/">'.$language['046'].'</a></div>';
unset($_SESSION['protect']);
}
echo '</div></div></div>';
break;
case 'auto':
$db->beginTransaction();
$sql = $db->prepare('SELECT * FROM `files` WHERE `id` = ?');
$sql->execute(array($_GET['id']));
$load = $sql->fetch();
$db->commit();
$protect = curl($load[4], 'http://vkontakte.ru/app'.$setup['app_id']);
preg_match('/content-length:\s(\d+)/i', $protect, $match);
if(strpos($protect, 'Content-Type: audio/mpeg') === false) {
$db->beginTransaction();
$sql = $db->prepare('INSERT INTO `error` (`file`,`text`,`attribut`) VALUES (?,?,?);');
$sql->execute(array($load[1],$language['1006'],'original'));
exit();
}
$tmp = './files/tmp/'.$load[1].'.size';
if(!file_exists($tmp)) file_put_contents($tmp, $match[1]);
if(copy($load[4], $load[6])){
require_once ('incfiles/getid3/getid3.php');
$getID3 = new getID3;
$getID3->setOption(array('encoding' => 'cp1251'));
$info = $getID3->analyze($load[6]);
tags();
$db->beginTransaction();
$sql = $db->prepare('UPDATE `files` SET `server` = ? WHERE `id` = ?');
$sql->execute(array(1,$load[0]));
$db->commit();
unlink($tmp);
exit();
} else {
$db->beginTransaction();
$sql = $db->prepare('INSERT INTO `error` (`file`,`text`,`attribut`) VALUES (?,?,?);');
$sql->execute(array($load[1],$language['1008'],'original'));
$db->commit();
exit();
}
break;

тут часть кода ну думаю смысл понятен