- 1
- 2
- 3
- 4
- 5
- 6
<?php
$data = file_get_contents("/path/to/photo.jpg"); // Read the file's contents
$name = 'myphoto.jpg';
force_download($name, $data);
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+155
<?php
$data = file_get_contents("/path/to/photo.jpg"); // Read the file's contents
$name = 'myphoto.jpg';
force_download($name, $data);
Я знаю конечно что это не говнокод, но последствия будут ужасными если не передать сразу же в функцию данные (т.к. PHP будет копировать содержимое дважды), представьте себе файл в 2МБ и много запросов, сервер капут в два раза быстрее.
- https://ellislab.com/codeigniter/user-guide/helpers/download_helper.html
inkanus-gray 16.09.2014 01:00 # +3
Всё-таки file_get_contents для тех случаев, когда содержимое нужно обработать.
volter9 16.09.2014 01:51 # 0
volter9 16.09.2014 02:43 # 0
Если вы знаете как это сделать (спрятать путь + скачать файл) через ваш способ то, может расскажите? )
1024-- 16.09.2014 02:54 # +4
http://cs405518.userapi.com/v405518237/24cf/2ul6NxnHApk.jpg
Во-первых, такой путь не будет обнаружен. Во-вторых, PHP не надо будет загружать и отдавать -- PHP не будет нагружать сервер.
Ещё, наверное, если всё секьюрно, можно перемещать файл в папку с нечитаемым именем только на небольшое время. Или менять конфиги сервера так, чтобы, из URL /24cf/2ul6NxnHApk указывал на нужную папку.
Но я не знаток в области ИБ, могу врать.
volter9 16.09.2014 03:41 # 0
А вообще так тоже сойдет.
> Ещё, наверное, если всё секьюрно, можно перемещать файл в папку с нечитаемым именем только на небольшое время. Или менять конфиги сервера так, чтобы, из URL /24cf/2ul6NxnHApk указывал на нужную папку.
Но я не знаток в области ИБ, могу врать.
А вообще можно крону задавать каждый час менять всем файлам имена. Но это фантазии и извращения. Вообщем можно что угодно придумать. Спасибо за ответ!
inkanus-gray 16.09.2014 04:31 # 0
P.S. Выяснилось, что у http_send_file докачка работает.
1024-- 16.09.2014 11:21 # 0
А то! Я тщательно картинку выбирал.
https://www.google.ru/search?q=userapi.com+няша&tbm=isch - вроде бы няши, да не все.
bormand 16.09.2014 13:40 # 0
Что-то боязно открывать картинку...
1024-- 16.09.2014 13:41 # 0
А картинка нормальная. Ничего плохого. Честно.
bormand 16.09.2014 18:05 # 0
laMer007 31.01.2016 22:23 # 0
Почему ридеректит на вк?
inkanus-gray 01.02.2016 00:53 # +1
CHayT 01.02.2016 12:21 # +1
где?
bormand 01.02.2016 17:16 # 0
В 3d.
inkanus-gray 16.09.2014 04:21 # +4
Рассмотрим другие варианты, которые могут спрятать URL:
1. Настроить привязку URL к путям файлов в конфиге сервера (Apache/lighttpd/nginx). Недостатком метода является то, что привязка будет статической и что требуется доступ к конфигу (что невыполнимо на общем хостинге).
Если я правильно понял, здесь нужна динамическая привязка, чтобы в следующий раз по этому URL файл нельзя было скачать, так?
2. http://php.net/manual/ru/function.http-send-file.php
Это именно то, что нужно. Во-первых, файл будет загружаться в память не целиком, а по частям, так что можно передавать хоть рипы фильмов. Во-вторых, исполнять передачу будет ядро пхп, а не высокоуровневый код. В-третьих, привязку можно делать динамической. И в-четвёртых, в учебном примере даже показано, как задать имя скачиваемого файла (http_send_content_disposition или просто послать заголовок Content-Disposition:).
3. Велосипедная реализация предыдущего пункта через загрузку и отдачу кусков файла в цикле или через загрузку в ОЗУ файла целиком (как в примере к CodeIgniter) — это хуже... хуже всего, в общем.
4. С помощью функции header послать серверу специальный заголовок, чтобы он отдал файл. Недостаток в том, что разные сервера требуют разный заголовок. Если установлен Apache, нужно послать X-SendFile:, если Nginx, то X-Accel-Redirect:, а если Lighttpd, то X-LIGHTTPD-send-file.
Возможно, возникнет вопрос, какой заголовок Content-Type нужно послать. Если отправить header('Content-Type: application/octet-stream'); то у пользователя браузер покажет диалог загрузки вместо открытия файла в браузере. CodeIgniter же не предлагает выбора Content-Type, он его определяет по расширению файла.
volter9 16.09.2014 18:40 # 0
Спасибо!
doo_dee_doo_dmt 19.09.2014 00:08 # +1
doo_dee_doo_dmt 19.09.2014 00:52 # +1
http://devel-m6w6.rhcloud.com/mdref/http
Я там вообще send file не нашел в доках. Про первую версию автор я так понимаю вообще забыл.
Наговнокодил в неймспейсах, но сделал нечто монструозное и малоюзабельное. Завязывать свой проект на такую какашку че-то не хочется, лучше уж завязать на конкретный веб-сервак (nginx например).
inkanus-gray 19.09.2014 01:09 # +1
Я не понимаю, как можно было такие разные проекты назвать одним именем.
inkanus-gray 22.09.2014 16:02 # +2
http://devel-m6w6.rhcloud.com/mdref/http/Env/Response/setContentDisposition
Энтерпрайз эдишн.
И судя по Accept-Ranges: в ответе даже докачка должна работать, как и в первой версии. Только вместо имени нужно отправлять дескриптор предварительно открытого файла.
inkanus-gray 16.09.2014 04:27 # +1
Итак, на входе есть содержимое файла. Но CodeIgniter определяет MIME-тип не по содержимому, а по расширению и даже запрещает отправку файла, полное имя которого не содержит точки.