PHP скрипт для скачивания файлов


Скачивание файла через скрипт

Нужно отдать юзеру .rar-архив на скачивание.

Проблема в том, что архивы в пару килобайт скачивает нормально, а вот если скачать архив в 10 мб, то пишет, что повреждён. В чём проблема?

2 ответа 2

Отдавать файлы средствами PHP — очень сомнительная идея.

Предлагаю Вам такой вариант с использованием nginx (так как он, говорят, работает со статикой лучше, чем Apache).

Чтобы скачать файл, пользователь должен перейти на некоторую страницу, к примеру:

После чего Вы по fileId определяете, что это за файл, и узнаете его путь, после того, как Вы узнали пусть, Вы создаете симлинк (symlink) на этот файл, например, в директории:

(там хранить только симлинки), при этом, имя симлинка — это, к примеру, md5() от оригинального пути к файлу + его расширение.
После того как Вы сгенерировали симлинк, Вы перенаправляете пользователя на него:

Пользователь переходит на этот симлинк и счастливый качает файл.

Для удаления симлинков Вы можете раз в несколько минут запускать сприпт по крону, который будет удалять все симлинки, созданные больше минуты назад, или же делать sleep(5) в скрипте, который генерирует симлинк и удалять его.

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

UPD

Кстати, PHP из коробки умеет делать симлинки.

Скачиваем файлы с помощью PHP и возможностью докачки

Давайте соберем воедино всю информацию, которую мы знаем о том, как отдавать файлы средствами PHP. Вообще, файлы можно отдавать напрямую средствами NGINX или Apache, но иногда требуется, чтобы мы могли учитывать количество скачиваний определенного файла или могли разрешать каким-то пользователям скачивать файл, а каким-то пользователям запрещать. Сделать это можно только в том случае, если за отдачу файла пользователю будет отвечать какой-то скрипт. В нашем случае, скрипт будет написан на языке PHP.

Давайте перейдем сразу к делу и напишем PHP код, который будет отдавать какую-то картинку с нашего сервера:

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

Проверить, включена ли буферизация вывода можно с помощью функции ob_get_level(). Подробнее об этой функции есть в официальной документации PHP. Если говорить коротко, то эта функция возвращает уровень вложенности буферизации. Если буферизация отключена, то функция вернет 0.

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

Функция ob_end_clean() очищает буфер вывода и отключает его, если он был включен. Если буфер был включен с помощью ob_start() и был какой-то вывод до вызова этой функции, то он будет удален.

Но вернемся к нашему коду. Допишем код скачивания, но теперь сделаем проверку на буферизацию и отключим ее, если она была включена:

Давайте теперь разберемся, что означают эти заголовки?

В этом заголовке мы даем понять браузеру, что будет скачана картинка в формате JPEG. Есть множество MIME типов и желательно, чтобы при отдаче файла вы указывали реальный MIME тип файла. В зависимости от этого типа файла, браузер у пользователя может показывать правильное окно для сохранения файла или сразу показывать файл в браузере. Список MIME типов можно посмотреть на странице в Википедии:

Прочитать правильный MIME тип файла перед его отправкой пользователю можно с помощью функции mime_content_type($filePath)

Если вы не хотите узнавать точный MIME тип файла, то можно воспользоваться универсальным MIME типом, который подходит для всех файлов — application/octet-stream:


Мы говорим браузеру: браузер, мы передали вам двоичный файл без указания точного формата файла. Делай с ним что хочешь. При этом не важно, какое будет расширение у файла. Это может быть картинка с расширением .jpg или .php

В этой строчке содержится описание того, что мы будем делать. Собственно на этом функционал этого header’a заканчивается. К сожалению, я не нашел точную информацию относительно строки File Transfer. Мне кажется, браузеры ее игнорируют.

Илон Маск рекомендует:  Видео на HTML-странице. Что такое HTML. Учебник по HTML.

Это очень важный header. При использовании этого header’a мы даем браузеру понять, что нужно скачать файл. Браузер при этом сам решает, скачивать файл автоматически или показать его в браузере. Все зависит от настроек браузера и от переданного MIME типа. Если мы передаем filename, то в браузер будет возвращен файл с этим именем. Очень полезно, когда скачивая картинку, у вас она скачивается с расширением .html или .php.

Остальные параметры не столь важны, за исключением Content-Length. С помощью параметра Content-Length мы передаем точный размер скачиваемого файла в байтах. В этом случае, в браузере будет реализован механизм просмотра оставшегося времени скачивания файла и сколько мегабайт уже скачалось.

Собственно, код скачивания файла готов, но у этого кода есть один очень серьезный недостаток. Код, который мы написали выше не поддерживает докачку файла. Если пользователи скачивают небольшие файлы, например картинки, то это не проблема. Но что делать, если размер файла больше гигабайта? Правильно! Организовывать докачку файла. Сделать докачку файла на PHP очень просто. Сначала я покажу готовый код:

Код очень простой, а благодаря комментариям, я думаю вы в нем разберетесь. Что мы делаем в коде выше? Да собственно ничего серьезного, проверяем существование файла, открываем файл на чтение, смотрим был ли передан range, чтобы пропустить то количество байт, которые пользователь скачал и в конце начинаем отдавать пользователю файл по 8192 килобайт. Это стандартный размер буфера функции readfile.

Код, представленный выше дает возможность скачивания файлов с помощью PHP. Вам остается лишь добавить по желанию запись в базу данных о скачиваемом файле или выполнить еще какие-то действия.

PHP: скачать файл с сервера

Я пробовал все виды кодов, которые я нашел, но ничего не помогло мне …

Когда я использую readfile () или fopen () или что-то вроде этого:

… Загрузка начинается, но файл всегда пуст …

вот последний код, который я пробовал:

Это источник моего кода: Исходный код

Я надеюсь, что вы можете помочь мне ��

Я использую Google Chrome
Мне нужна ваша помощь для этого маленького проекта: Ссылка на проект

При нажатии на файл в выпадающем списке появляется «herunterladen» (скачать на немецком языке), вот где я хочу начать загрузку кода php

Мне просто нужна самая основная функция загрузки для PHP … почему на w3schools есть пример загрузки, а НЕ пример загрузки? оо

Отдача файлов на скачивание PHP

В PHP отправка файла в браузер на скачивание осуществляется в 2 этапа:

Отправка заголовков

Первый вариант с явным указанием типа файла mime:

Второй, application/octet-stream – «двоичный файл без указания формата».

Заголовок с размером файла – header(‘Content-Length: ‘ . filesize($file)); можно не указывать.

Чтение и вывод файла

Перед отправкой файла нужно убедится что буферизация вывода отключена с помощью ob_get_level() или сбросить и отключить ее функцией ob_end_clean() .

Непосредственно чтение и вывод файла можно сделать следующими функциями:


Php скрипт для получения ссылок для скачивания файлов с Яндекс диска (Использование API)

Дубликаты не найдены

Че то я тоже на этой строчке залип.

ТС, а на кой хер там счетчик?

Еще название переменной йеху тоже ниче так прикол :)

эм.а смысл?хотя для читабельности $count = count($res[_embedded][items]) вынести бы за цикл

да ладно,бывает и хуже)

Меня всегда поражают подобные циклы. Ошибка может возникнуть из ниоткуда, а отслеживать её будет интересно.

Я бы ему рекомендовал одной строкой весь код писать. Весьма удобно. Главное это монитор пошире приобрести.

Выглядит как заклинание черной магии

да и писать данный толмут было не просто

что это за слово такое?

у тебя $dir вообще не существует. И $content тоже потом.

Вывод ошибок при написании ты явно не включал. Или сознательно отключал.

$fields= ‘_embedded.items.name’; на хрена наплодил переменных ненужных? Здесь ты загна в нее строку, для того, что бы вставить через две строчки эту переменную в. СТРОКУ! Все, больше это не используется.

И да, строковые ключи экранировать принято.

В общем,пока слабая тройка с минусом :-)

И включай вывод ошибок при разработке.

Можно, с помощью stream_context_create, но я бы тоже по старинке через старый добрый curl делал

Ну такиех уже даже бесплатных хостингов нет ) А foreach чего предлагать, это единственное тут разумное решение.

Так я ж про хостинги говорю, а не про это всемирнопозорное убожество

Ты же сам сказал, что у него curl не установлен :) у меня даже на бесплатном хостинге и то был. :) А без шуток, бегет убогий хостинг по соотношению цена/качество. А это главный критерий для хостинга. Я уж не говорю про своевременное обновление серверного ПО

Илон Маск рекомендует:  Обмен ссылками

а там сразу получить все ссылки на файлы нельзя?запрос в цикле( p.s $content = file_get_contents($dir); а это тут зачем?

быстро правишь :D

я здесь чисто для получения советов от более опытных, поэттому стараюсь эти совет применять

Имхо, хотел бы советов — спросил бы их. А не постил тупо портянку говнокода (сорян, но по другому никак), без даже намёка на необходимость советов, что в теле, что в названии, что в тэгах.
з.ы.
Чтобы не быть голословным (кому-то может показаться вкусовщиной и дикими придирками, но мне похуй):
1) Что за, блять, дикая мешанина из строк и их конкатенации на вызове curl_init? У самого глаза не ломаются и не вытекают при попытке её чтения? Я понимаю, что «канпелятар» — машина и всё стерпит, но, всё же, — лучше в «отдельное» выносить;
2) В догонку, к предыдущему — длина строк. Жесткого ограничения нет, но хороший тон — 80 символов. Читать PSR-2;
3) Экранировка ключей массива, уже писали выше;
4) Я, блджад, конечно понимаю, что пример с курлом откуда-то скопирован и подправлен, но, хотя бы, имена переменных смени. Имя переменной должно хоть как-то указывать на то, что в ней. А с этими $res/$ch/$exy, что ты, что я, что все остальные — в душе не ебём, без «парсинга» близлежащего кода, что в них находится;
5) Почему $yd_file = ‘/files/’.$filesname;? А $path объявленный в самом начале зачем? Либо это мусорная переменная, либо используй уже существующее;
6) Учитывая, что и лимит и пермишны в первом запросе ты задаёшь жёстко — можно не пихать их в отдельные переменные — какая хрен разница в данном случае, когда по запросу и так ясно, что limit — это лимит возвращаемых данных, а fields — набор полей. Вот если бы это всё было разбито по методам и эти параметры передавались в метод который бы возвращал готовый урл — а так, только если ради комментария на объявления этих переменных;
7) Имхо, зачем for? Почему не foreach ($res[_embedded][items] as $itemData) < $fileName = $itemData['name'];>?;
8) Закрывающий тэг ?> — не нужен. В файле нет ничего кроме php кода. Туда же и пустая строка в конце файла.
9) Читать PSR’ы, хотя бы 1 и 2, можно ещё и 12 зацепить, но он, де-факто, «не принят»;
з.з.ы.
Код не запускал, всё — чисто «на глаз».
Сорян, если показался резок — дело к ночи, а я ещё работаю.


Все для создания своего сайта

В прошлый раз мы рассмотрели вариант формы для загрузки файла. Сегодня подробно разберем скрипт-обработчик загрузки файла на языке php.

Код файла обработчика следующий:

Скрипт загрузки файлов на сервер php

В данном примере мы рассмотрим вариант скрипта загрузки файлов на сервер php. Для простоты примера будем загружать на сервер файлы графического формата.

В начале присваиваем переменной $_POST[‘action’] значение $action , затем проверяем содержит ли $action значение send. Если равенство $action==”send” верно, значит данные пришли именно из нашей формы и запускаем работу скрипта.

Далее, проверяем наличие файла в глобальном массиве $_FILES , проверяем существование файла при помощи функции empty()

if(empty($_FILES[‘myfile’][‘name’])),

если глобальная переменная $_FILES пустая, прекращаем работу скрипта и выводим ошибку («Вы не выбрали файл для загрузки»).

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

Проверяем размер загружаемого файла. Это очень просто — все прописано в любом файле в самом массиве $_FILES[`myfile`][`size`]; Допустимый размер вы задаете сами в переменной $filSIZE=10000; Напишите любое число которое вам нужно. Если с объемом файла все в порядке и он не превышает вами заданный размер, можно приступать к загрузке файла на ваш сервер.

Тут есть один нюанс: название файла можно менять или переименовать его по своим правилам.

Названия многих файлов могут совпадать и содержать одни и те же имена. Например, 1.jpg, file.jpg, default.png и так далее. Вариантов масса и если имена совпадут, своего нужного файла вы не найдете. Поэтому будем переименовывать файлы по своему алгоритму.

Как создать уникальное имя для своего файла?

Об этом написана целая тема и прочитать можно здесь. А пока идем дальше. Копируем временный файл $_FILES[‘myfile’][‘tmp_name’] в ту директорию или папку, где будут храниться все файлы, которые вы будете загружать к себе на сервер.

Илон Маск рекомендует:  Mploye cpp реализация обработки событий на c

В нашем случае мы пропишем название директории в переменной $dir.
Все, скопировали файл в нужную директорию, теперь запишем все данные в базу данных.

Чтобы можно было быстро найти наш файл по его id из базы данных. А в папке их может быть сколько угодно. Хоть тысяча, хоть десять миллионов. Все зависит от сервера на котором установлена форма для загрузки файла.

Отдаем файлы эффективно с помощью PHP

Когда вообще нужно отдавать файлы через PHP? Например, когда нужно собрать какую-то статистику скачиваний файла или осуществить запрет на скачивание файлов, позволив скачивать по ссылке только один раз и ограниченной группе пользователей.

Допустим, чтобы скачать какой-то файл, мы отправляем пользователя не на прямую ссылку с расположением файла:

а на адрес скрипта, который отдает пользователю файл через PHP:

Где, в параметр file, для скрипта можно передавать идентификатор файла, который требуется скачать, после чего можно выстраивать различные проверки и выдавать пользователю файл для скачивания:

Сделать это можно несколькими способами, о которых речь пойдет ниже.

Функция readfile()

Этот метод будем применять в специально созданной функции. Такая функция поможет отправлять даже большие файлы, PHP будет отдавать файл пользователю по частям. Функция ждет, когда файл будет прочтен и отдан.

Чтение и отправка файла вручную


Эта функция аналогична той, которая описана выше, но для чтения и отдали файла используются: fopen, feof, fread, fclose. Функция ждет когда файл будет прочитан и отдан, также позволяет экономить память.

Отдаем файл через сервер

Отдать файл можем не скриптом, через PHP, а с помощью Apache или Nginx. Отдача файла средствами сервера дает максимальное быстродействие, минимум потребляет памяти и ресурсов сервера.

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

Функция для отправки файла будет следующей:

Nginx умеет отправку файла из коробки, все что нужно, настроить конфиг, указав запрет на доступ к каталогу (my/path/protected/):

PHP скачивание файлов по списку URL

Доброго времени уважаемые читатели. Очередной пост — заметка, на тему PHP скачивание файлов по списку URL. Из заголовка поста думаю уже становится ясно о чем пойдет речь. Перейдем к сути дела.

Задача: Скачать большое количество файлов расположенных на удаленном сервере(серверах) имея при этом список адресов URL этих файлов. Это могут быть как каталоги картинок, программ или чего либо еще.

Решить данную задачу можно с помощью просто PHP скрипта с использованием CURL.

Список URL файлов

В результате имеем папку с закаченными файлами из удаленных источников.

Куда применить? Иногда такой метод применяется для скачивания картинок дизайна какого нибудь сайта донора. Список адресов картинок можно получить из его файла стилей CSS. (Это конечно может использоваться как в благих целях, так и в целях плагиата. Мною подразумеваются конечно же исключительно положительные цели)

Скачивание файлов по временным ссылкам

Наверное каждому приходилось сталкиваться с временными ссылками при скачивании фильмов, музыки, программ и т.п. Зачем это делается? Да чтобы другие сайты не размещали ссылки на файлы, которые расположены на нашем сайте. Давайте посмотрим, как написать скрипт, который будет генерить временные ссылки.

Для хранения информации о файлах и временных ссылках будем использовать БД. Таблица files хранит информацию о файлах:

  • id — уникальный >title — название файла, например, «Текстовой редактор NotePad++»
  • description — описание файла, например, «Бесплатный редактор текстовых файлов (замена стандартного Блокнота) с поддержкой синтаксиса большого количества языков программирования, ориентирован для работы в операционной системе MS Windows»
  • filename — имя файла для скачивания, например, NotePadPP.zip
  • mimetype — MIME-тип файла

Таблица downloads хранит информацию о временных ссылках:

  • file_id — уникальный >uniq_id — временная ссылка
  • puttime — время создания ссылки

Файлы для скачивания расположены в директории DOCUMENT_ROOT/download/files/ . Эта директория должна быть защищена с помощью .htaccess :

Загрузка файлов на сайт: PHP, AJAX, HTML5 и Drag’n’Drop

Скучные формы загрузки — прошлый век. HTML5 дает возможности, чтобы добавить Drag’n’Drop, а AJAX позволяет загружать файлы без обновления страницы.

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

Программисту нужно позаботиться о том, чтобы посетитель смог сделать это максимально удобно. Загрузить файл на сайт можно и с помощью обычной формы и обработчика на PHP, но с выходом HTML5 появились другие интересные возможности — в этой статье мы поговорим и о базовых функциях, и о нововведениях.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL