Выдача файла php скриптом
1.
CROWS (02.03.2011 / 17:07)
session_start();
if (!isset($_SESSION['load']) || $_SESSION['load']=="" || $_SERVER['HTTP_REFERER']!=="http://site.org/file".$_GET['id']."")
{
Header ('Location: http://site.org/file'.$_GET['id']);
exit();
}else{
$file = ("путь к файлу");
header ("Content-Type: application/octet-stream");
header ("Accept-Ranges: bytes");
header ("Content-Length: ".filesize($file));
header ("Content-Disposition: attachment; filename=".$file);
readfile($file);
}
2.
KOZZ (02.03.2011 / 17:07)
http://www.manhunter.ru/webmaster/179_zaschita_faylov_na_servere_ot_pryamih_ssilok_antileech.html
3.
CROWS (02.03.2011 / 17:11)
Суть вот в чем:
на сайте есть страницы с описанием файлов (http://site.org/file'.$_GET['id']). На этой странице расположена ссылка на скачивание файла, код скачивания файла выше. Это сделано с той целью, чтобы скрыть прямые ссылки и чтобы скачивать файл можно было только прийдя с
http://site.org/file'.$_GET['id']
В связи с тем, что мы изменяем прямой адрес к файлу на адрес
http://site.org/load'.$_GET['id'], выдача файла происходит с помощью php скрипта (код в else).
Но вот огромная проблема есть: при скачивании файла все 256 МБ оперативы забиваются за раз.
Как решить проблему?
4.
KOZZ (02.03.2011 / 17:14)
может что то типа flush() ??
я тебе ссылку дал, там подобный скрипт только все разжевано и удобно.
5.
CROWS (02.03.2011 / 17:16)
Ботаник eGo (2 Марта 2011 / 17:14)
может что то типа flush() ??
я тебе ссылку дал, там подобный скрипт только все разжевано и удобно.
Сейчас посмотрю, только врядли там найдется решение этой проблемы.
6.
Lugaro (02.03.2011 / 17:19)
2.
Ботаник eGo, Там косяк в нем, при выдаче юзер не получит сразу файл, а будет ждать пака скрипт полностью не выдаст файл, в циклах flush() нужно добавить.
7.
KOZZ (02.03.2011 / 17:20)
6.
.::lugaro::., там по - моему это указано где - то..
P.S: я об этом в 4 посте говорил
8.
Дмитрий (02.03.2011 / 17:20)
1) Накатай файл-ресайз (типа как ресайз фотографий в моторе) и выдавай файлы через него.
2) Чтобы при каждом скачивании ссылка была разная, прикрепляй к джет-запросу сгенерированный код, а сам код пиши в сессию.
3) При скачивании проверяй, если код из ссылки совпадает с кодом в сессии, выдавай TRUE и отдавай файл, в протифном случае - FALSE.
4) При удачном совпадении и удачной загрузке снова генерируй код и перезаписывай сессию.
5) Путь к файлу ресайза для пущей красоты скрой с помощью мод-реврайта.
К примеру, вместо
http://site.ru/resize.pgp?fail=12345&specialkod=12345679&
измени на
http://site.ru/12345/12345679
Вот и вся любовь. По сути, работы на 15 минут.
9.
Lugaro (02.03.2011 / 17:23)
7.
Ботаник eGo, точно, это я же и писал
10.
Дмитрий (02.03.2011 / 17:23)
о том как отдать различные расширения файлов с помощья ресайза, читай тут:
http://www.ipm.kstu.ru/it/lec/7.php
11.
CROWS (02.03.2011 / 17:29)
8.
dima.london, нет, файлы должны быть в том же виде, что они и есть. По второму и третему пункту: дак полный путь надо будет выдавать.
Добавлено через 02:19 сек.
И можно обойтись без дополнительных параметров в GET, а просто сессией, т.е. так, как я написал в первом посте.
Добавлено через 04:54 сек.
4.
Ботаник eGo,
while (!feof($f)) {
flush();
if (connection_aborted()) {
fclose($f);
break;
}
echo fread($f,10000);
sleep(1);
}
Так или его после нужно ставить?
12.
Дмитрий (02.03.2011 / 17:36)
11.
-V_o_R_o_N_a-, при чем здесь полный путь? К примеру, в файле ресайда пропиши папку и подпапку, где прячешь файл, а в джет-запросе передавай только имя файла и сгенерированный код.
Сейчас поищу код как я себе сделал выдачу мп3-файлов с помощью ресайза.
13.
CROWS (02.03.2011 / 17:39)
12.
dima.london, ок, жду.
14.
Дмитрий (02.03.2011 / 17:45)
Вот так выглядит у меня файл выдачи мп3-файла (mp3.php):
if(isset($_GET['file'])) {$file = $_GET['file'];} else {$file = '';}
if (preg_match('|^[a-z0-9_\.\-\/]+$|i', $file)){
$ext = strtolower(substr($file, strrpos($file, '.') + 1));
if($ext == 'mp3'){
$filename = 'папка/подпапка/' . $file;
$filename = file_get_contents($filename);
header('Content-Disposition: inline; filename="' . $file . '"');
header('Content-type: audio/mpeg');
header('Content-Length: ' . strlen($filename));
echo $filename;
}
}
exit;
Ссылка на скачивание имеет 2 переменные (ид файла в базе и сгенерированный код из сессии).
Путь к загрузке лежит через простенький скрипт, где у меня идет проверка сгенерированного кода на совпадение с сессией, существование файла и запись количества скачиваний (+1).
То есть если все гут, я пишу +1 скачивание и отдаю файл:
header ('Location: mp3.php?file=имя_файла.mp3); exit;
15.
CROWS (02.03.2011 / 17:49)
14.
dima.london, благодарю за код.
А file_get_contents и echo тоже ведь будут оперативу хавать) Файн, например в 100 МБ, а оперативы на ВДС 256)
16.
Дмитрий (02.03.2011 / 17:49)
Преимущества:
1) Прямой путь к файлу скрыт. Скачать по прямой ссылке невозможно.
2) В ссылке есть сгенерированный код из сессии, что создает большие трудности для скачивания файла роботом или для граба твоего контента.
Ну, для себя, для пущей безопасности и накрутки количества скачиваний роботами, для гостей я добавил еще и каптчу.
Добавлено через 01:21 сек.
хз, не должно. Хотя, вроде как хавает.
17.
CROWS (02.03.2011 / 17:55)
выдача ведь тоже скриптом происходит.
18.
Lugaro (02.03.2011 / 19:42)
11. Перед sleep напиши
14.
dima.london, Загнется твой скрипт при больших файлах, да и нет возможности докачки что не мало важно
15. file_get_contents будет
19.
Саня (02.03.2011 / 20:48)
$ext = strtolower(substr($file, strrpos($file, '.') + 1)); // костыль детектед
//Good
$ext = pathinfo($file,PATHINFO_EXTENSION);
20.
Сааааа-нёёёёё-к (02.03.2011 / 20:53)
так проще запоминаеться))
$ext = pathinfo($file);
echo $ext['extension'];
21.
Дмитрий (03.03.2011 / 14:23)
.::lugaro::., Ботаник eGo, вариант из 4 поста работает в 2-3 раза дольше, даже при использовании flush(). К тому же не поддерживает потоковое воспроизведение файла.
Возможно, я что-то не так делаю. Из того кода я только изменил директории на свои, добавил flush() (что само собой существенно ускорило отдачу файла) и изменит MIME тип файла на audio/mpeg (так как использую для обработки мп3-файла.
Все равно, скорость на порядок ниже той, если просто выдавать файл как я описал в моем варианте).
22.
KOZZ (03.03.2011 / 14:40)
dima.london, я даже не представляю как допустим твой file_get_contents() выдаст файл в 500++ мб.
да и не думаю что file_get_contents() быстрее fread например.
без докачки очень худо будет тоже
P.S:
<?
if(isset($_GET['file'])) {$file = $_GET['file'];} else {$file = '';}
# а ведь так элегантней:
$file = (isset($_GET['file'])) ? $_GET['file'] : '';
?>
23.
Дмитрий (03.03.2011 / 14:52)
22.
Ботаник eGo, само сабой так элегантнее.
Я просто надеюсь на твою помощь. Все-таки и я решил добавить докачку, но явно что-то делаю не так.....
24.
Lugaro (03.03.2011 / 15:30)
21.
dima.london, Ну дык там же sleep стоит и отдается кусками по 10кб в сек, поменяй скорость и выдавай кусками по больше + если тестил на денвере flush там до балалайки
URL:
https://visavi.net/topics/19287