Curl не загружает большой файл
Обновлено: 21.11.2024
Добро пожаловать в учебник по загрузке файлов с помощью PHP CURL. Нужно получить файл с другого сервера с помощью PHP CURL? Да, это возможно.
- $fh = fopen("ФАЙЛ", "w");
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, "HTTP://SITE.COM/FILE");
- curl_setopt($ch, CURLOPT_FILE, $fh);
- curl_exec($ch);
- curl_close($ch);
Это должно охватывать основы, но давайте рассмотрим еще несколько примеров в этом руководстве. Читайте дальше!
ⓘ Я включил zip-файл со всем исходным кодом в начале этого руководства, поэтому вам не нужно копировать и вставлять все… Или если вы просто хотите сразу погрузиться.
БЫСТРЫЕ СЛАЙДЫ
СОДЕРЖАНИЕ
СКАЧАТЬ И ПРИМЕЧАНИЯ
Во-первых, вот ссылка для загрузки примера кода, как и было обещано.
БЫСТРЫЕ ЗАМЕЧАНИЯ
Если вы заметили ошибку, не стесняйтесь комментировать ниже. Я тоже стараюсь отвечать на короткие вопросы, но это один человек против всего мира... Если вам срочно нужны ответы, посмотрите мой список веб-сайтов, чтобы получить помощь по программированию.
СКАЧАТЬ ПРИМЕР КОДА
Нажмите здесь, чтобы загрузить весь исходный код примера. Я выпустил его под лицензией MIT, так что не стесняйтесь строить на его основе или использовать в своем собственном проекте.
СКАЧАТЬ ФАЙЛ PHP CURL
Хорошо, теперь давайте перейдем к примерам загрузки файлов с помощью PHP CURL.
ПРИМЕР 1) ИСПОЛЬЗОВАНИЕ CURL ДЛЯ ЗАГРУЗКИ ФАЙЛОВ
- Куча настроек, откуда скачать файл, куда его сохранить.
- Создание файла на локальном сервере.
- Сам запрос CURL.
- Обработка ошибок и действия после загрузки.
ПРИМЕР 2) СКАЧИВАНИЕ БОЛЬШИХ ФАЙЛОВ
Если вы имеете дело с очень большими файлами, я рекомендую отказаться от CURL и вместо этого просто использовать fopen-fwrite-fread. Мы можем ограничить количество байтов, которое функция fread() может прочитать за один раз, чтобы предотвратить ошибка памяти».
ПРИМЕР 3) СУПЕР ПРОСТАЯ ЗАГРУЗКА
Для вас, ребята, которые просто хотят очень простую загрузку файлов... На самом деле нам даже не нужен CURL. Просто file_put_contents() и file_get_contents() .
ПОЛЕЗНЫЕ ИНФОРМАЦИИ И ССЫЛКИ
Это все, что касается руководства, и вот небольшой раздел с дополнительными материалами и ссылками, которые могут быть вам полезны.
ССЫЛКИ И ССЫЛКИ
ОБУЧАЮЩЕЕ ВИДЕО
ИНФОГРАФИЧЕСКАЯ Шпаргалка
КОНЕЦ
Спасибо, что прочитали, и мы подошли к концу. Я надеюсь, что это помогло вам лучше понять, и если вы хотите поделиться чем-либо с этим руководством, пожалуйста, не стесняйтесь комментировать ниже. Удачи и удачного кодирования!
Оставить комментарий Отменить ответ
Поиск
сообщить об этом объявлении
Прорыв в Javascript
Сфотографировать с помощью веб-камеры? Голосовые команды? Видеозвонки? Да, это возможно с помощью Javascript — ознакомьтесь с прорывом Javascript!
сообщить об этом объявлении
Существует ли существующий инструмент, который можно использовать для загрузки больших файлов через плохое соединение?
Мне приходится регулярно загружать относительно небольшой файл: 300 МБ, но медленное (80-120 Кбайт/сек) TCP-соединение случайным образом обрывается через 10-120 секунд. (Это сеть крупной компании. Мы несколько раз связывались с их администраторами (работающими из Индии), но они ничего не могут или не хотят делать.) Проблема может заключаться в их обратных прокси-серверах/балансировщиках нагрузки.
Я изменил эту строку:
Мне пришлось добавить --speed-limit 2048 --speed-time 10, потому что при сбое соединение обычно зависает на несколько минут.
Но в последнее время даже этот скрипт не может завершиться.
Одна из проблем заключается в том, что он, кажется, игнорирует часть -C -, поэтому он не "продолжает" сегмент после повторной попытки. Кажется, что он усекает соответствующий временный файл и начинает с начала после каждого сбоя. (Я думаю, что параметры --range и -C нельзя использовать вместе.)
Другая проблема заключается в том, что этот скрипт загружает все сегменты одновременно. В нем не может быть 300 сегментов, из которых одновременно загружаются только 10 сегментов.
ОБНОВЛЕНИЕ 1: Дополнительная информация: функциональность параллельной загрузки не следует удалять, поскольку они имеют ограничение пропускной способности (80-120 Кбайт/с, в основном 80) на соединение, поэтому 10 соединений могут привести к 10-кратному ускорению. Мне нужно закончить загрузку файла за 1 час, потому что файл создается ежечасно.
Вы ищете инструмент командной строки для написания сценариев?Потому что в противном случае я бы просто использовал FileZilla или аналогичный ftp/sftp-клиент, поддерживающий перезапуск загрузки.
7 ответов 7
lftp (Википедия) подходит для этого. Он поддерживает ряд протоколов, может загружать файлы, используя несколько одновременных параллельных подключений (полезно, когда большая потеря пакетов не вызвана перегрузкой) и может автоматически возобновлять загрузку. Это также можно написать в сценарии.
Включая точную настройку, которую вы придумали (спасибо вам):
Спасибо. Я пробовал это, но похоже, что параллельные соединения не используются: lftp -e 'set net:timeout 15; установить сеть: максимальное количество попыток 0; установить сеть: переподключение-интервал-база 3; установить сеть: переподключение-интервал-макс. 3; pget -n 10 -c "https://host/file.tar.gz"; выход'
О, когда я удалил параметр "net:timeout", он стал параллельным. Но через какое-то время замедляется. Думаю, потому что соединения начинают "зависать".
Обратите внимание, что lftp поддерживает торрент в качестве базового протокола передачи. Используй это. Все другие протоколы, которые он поддерживает, не поддерживают обнаружение/исправление ошибок для каждого фрагмента и полагаются на TCP для обеспечения обнаружения ошибок. Обратите внимание, что торрент использует обнаружение ошибок TCP, но помимо этого проверяет хэш sha1 всего вашего файла, а также каждого блока, передаваемого по сети. По моему опыту, фильм размером 4 ГБ, передаваемый через торрент через сеть 4G, обычно имеет около двух ошибок проверки хэша. Это означает, что TCP считает полученный пакет безошибочным, даже если он был поврежден
Я не могу проверить это для вас в вашей ситуации, но вы не должны использовать --range с -C - . Вот что на эту тему написано на справочной странице:
Используйте -C -, чтобы заставить curl автоматически определять, где/как возобновить передачу. Затем он использует заданные выходные/входные файлы, чтобы выяснить это.
Попробуйте вместо этого:
Кстати, 120 КБ/с – это примерно 1,2 Мбит/с – это типичная скорость загрузки xDSL во многих частях мира. 10 секунд на МБ, то есть чуть меньше часа на весь файл. Не так медленно, хотя я ценю, что вы больше заботитесь о надежности, чем о скорости.
Спасибо. Такой подход сработает, но он медленный, потому что не загружается параллельно. У них есть ограничение скорости на соединение, и я должен закончить загрузку за 1 час, потому что они ежечасно генерируют файл. Обновление вопроса.
Возможно, вам больше повезет с wget --continue :
Нестандартно: наденьте повязку на глаз и используйте BitTorrent. Сделайте размер блока маленьким при создании торрента. Очевидно, зашифруйте файл, чтобы любой, кто найдет торрент, не получил ничего полезного.
Именно. Даже если соединение действительно плохое и файл каким-то образом был поврежден, все должно работать нормально. СОВЕТ ПРОФЕССИОНАЛА: зашифруйте его, переименуйте в «KimKardashianNude.mp4» и позвольте тысячам людей помочь вам с подключением. Автоматическое распределенное резервное копирование бесплатно! :)
Как сказал сам Линус: "Только слабаки используют резервное копирование на магнитную ленту: настоящие мужчины просто загружают свои важные файлы на ftp, а остальной мир копирует их ;)"
@RonJohn Я знаю, что это редко используется, но это не значит, что его нельзя использовать. Протокол BitTorrent очень хорошо справляется с плохим соединением.
@LorenPechtel рабочий заказ для RISK для утверждения портов, рабочий заказ для NOC для открытия портов, и рабочий заказ для групп Linux и Windows для установки торрент-клиентов, и еще один рабочий заказ для мониторинга их всех, чтобы только одобренные файлы передаются. И ничто из этого не принимает во внимание HIPPA, PCI или тот факт, что файл, который должен идти из точки A в точку B, теперь перемещается из точки A в точки C, D, E, F, G, H, I и J раньше. добраться до точки Б. RISK не одобрит именно эту причину.
У меня была такая же проблема на предыдущей работе (за исключением резервных копий удаленных баз данных объемом более 300 ГБ при нестабильном соединении (из офиса)). У пользователей были серьезные проблемы с загрузкой файла размером более прибл. 1 ГБ до разрыва соединения. Поскольку они использовали стандартный файл копирования/вставки Windows через соединение RDP, неудивительно.
Одна вещь, которую я обнаружил, заключалась в том, что наши настройки VPN полностью не соответствовали настройкам сети (в основном длина MTU). Во-вторых, копировщик файлов Windows НЕ предназначен для копирования файлов через Интернет.
Моим первым решением был простой FTP-сервер, однако он не решил проблему времени передачи (часто 3-4 часа при нашем соединении).
Вторым решением было использовать Syncthing для отправки файлов непосредственно на внутренний NAS. Каждую ночь после завершения резервного копирования Syncthing отправлял все необходимое обратно на NAS в офисе.Мало того, что была решена проблема с 3+ часами времени передачи, я еще и избавился от 1-2 часов, чтобы доставить данные в случае кризиса. Каждое утро в 8 утра файлы на NAS обновлялись, и у нас были готовы резервные копии. Даже с огромными файлами (в какой-то момент база данных почти 700 ГБ) я еще не сталкивался с повреждением файлов или другими проблемами.
Syncthing очень прост в настройке и управлении, доступен для всех платформ (даже для телефонов) и очень хорошо обрабатывает плохие соединения. Если соединение обрывается, Syncthing просто ждет несколько минут и повторяет попытку. р>
Вам нужна локальная папка для синхронизации, но ваши файлы будут доступны почти сразу после их обновления.
Еще одно преимущество синхронизации заключается в том, что ее можно настроить на синхронизацию только изменений в файле (как при дифференциальном резервном копировании). возможно, решение части вашей проблемы с пропускной способностью.
Инструмент curl позволяет нам получить заданный URL-адрес из командной строки. Иногда мы хотим сохранить веб-файл на свой компьютер. В других случаях мы можем направить его прямо в другую программу. В любом случае, curl поможет нам.
Это основное использование curl :
Давайте попробуем с базовым адресом веб-сайта:
Помимо отображения индикатора выполнения (о котором я объясню ниже), у вас мало указаний на то, что curl действительно скачал. Итак, давайте подтвердим, что файл с именем my.file действительно был загружен.
Использование команды ls покажет содержимое каталога:
И если вы используете cat для вывода содержимого my.file , вот так:
Я думал, Unix должен быть тихим?
Давайте немного вернемся назад: когда вы впервые запустили команду curl, вы, возможно, увидели быстрый мигающий индикатор выполнения:
Если вы помните Основы философии Unix, один из принципов:
Правило молчания: когда программа не может сказать ничего удивительного, она не должна ничего говорить.
В примере с curl автор, по-видимому, считает важным сообщать пользователю о ходе загрузки. Для очень маленького файла такое отображение состояния не очень полезно. Давайте попробуем это с большим файлом (это файл с именами детей из Администрации социального обеспечения), чтобы увидеть, как анимируется индикатор выполнения:
Небольшое примечание: если вы новичок в командной строке, вы, вероятно, привыкли к тому, что команды выполняются каждый раз, когда вы нажимаете Enter. В данном случае команда такая длинная (из-за URL-адреса), что я разбил ее на две строки с помощью обратной косой черты, т. е. \
Это исключительно для облегчения чтения. Что касается компьютера, то он просто соединяет две строки вместе, как если бы этой обратной косой черты не было, и выполняет это как одну команду.
Отключить curl
Индикатор хода выполнения завитка — хорошая возможность, но давайте просто посмотрим, сможем ли мы заставить завиток работать так же, как и все наши инструменты Unix. В документации параметров curl есть параметр молчания:
-s, --silent
Тихий или тихий режим. Не показывать индикатор прогресса или сообщения об ошибках. Делает Curl немым. Он по-прежнему будет выводить данные, которые вы запрашиваете, потенциально даже на терминал/стандартный вывод, если вы не перенаправите их.
Повторять и ломать вещи
Итак, это основы команды curl. Есть много других вариантов, но на данный момент мы знаем, как использовать curl, чтобы сделать что-то действительно очень мощное: получить файл из любого места в Интернете из простых ограничений нашей командной строки.
Прежде чем двигаться дальше, давайте посмотрим, как можно переписать эту простую команду и, что более важно, испортить ее:
Сокращенные варианты
Как вы могли заметить в документации --silent, здесь указана альтернативная форма -s . Многие опции для многих инструментов имеют сокращенный псевдоним. На самом деле --output можно сократить до -o
Теперь будьте осторожны: количество дефисов — это не то, что вы можете напутать; следующие команды вызовут ошибку или другое непредвиденное поведение:
Кроме того, обратите внимание на позицию my.file , которую можно рассматривать как аргумент опции -o. Аргумент должен следовать после -o …потому что curl .
Если вместо этого вы выполнили это:
Откуда curl узнает, что my.file , а не -s является аргументом, т.е. как вы хотите назвать содержимое загруженного URL?
На самом деле, вы можете увидеть, что создали файл с именем -s…, который не является концом света, но и не является чем-то, чего вы невольно хотите.
Порядок вариантов
По большому счету (насколько мне пришло в голову), порядок параметров не имеет значения:
Несколько замечаний:
-
То, как URL-адрес, который вы можете считать основным аргументом команды curl, может быть размещен в любом месте после команды, не предназначено для всех команд. Так что всегда полезно читать документацию перед каждой новой командой.
И у вас возникнет проблема.
Вообще никаких вариантов
Последнее, что нужно учитывать, это то, что происходит, когда вы просто выбираете URL без параметров (которые, в конце концов, должны быть необязательными). Прежде чем попробовать, подумайте о другой части философии Unix:
Это философия Unix: писать программы, которые делают одну вещь и делают ее хорошо. Пишите программы для совместной работы. Напишите программы для обработки текстовых потоков, потому что это универсальный интерфейс.
Если вы используете curl без каких-либо опций, кроме URL-адреса, содержимое URL-адреса (будь то веб-страница или двоичный файл, например изображение или ZIP-файл) будет распечатано на экране. Попробуйте:
Если вам нужен быстрый ответ, команда curl -O позволяет использовать утилиту командной строки curl для загрузки файла. Конечно, о загрузке файлов с помощью curl можно узнать гораздо больше, чем просто параметр -O.
Здесь мы предоставим примеры для нескольких команд загрузки curl, которые вы можете использовать для удовлетворения различных требований. Если вы новичок в керлинге, мы рекомендуем прочитать статью от начала до конца. Если вы знакомы с curl, но просто хотите освежить в памяти знания, смело переходите к определенному разделу.
Поскольку curl часто «просто работает», обладает высокой переносимостью и устанавливается по умолчанию во многих системах, а также является стандартом де-факто в документации по API, он пользуется популярностью среди разработчиков и инженеров DevOps.
Если вы используете современную операционную систему Linux, у вас, вероятно, есть все необходимое для работы. Чтобы быть уверенным, вот предварительные условия:
- curl — curl установлен по умолчанию в большинстве популярных операционных систем *nix, включая macOS. Он также доступен в современных операционных системах Windows. Вы можете проверить, установлен ли curl, выполнив команду curl -V из терминала. Результат должен выглядеть примерно так:
Если вы используете Linux и у вас не установлен curl, скорее всего, вы сможете загрузить его с помощью диспетчера пакетов вашей операционной системы по умолчанию (например, apt, yum или zypper). Здесь есть ссылки для скачивания curl для множества других операционных систем.
💡 Совет для профессионалов: вы можете комбинировать параметры завитка. В большинстве наших примеров мы будем использовать один или два параметра команды curl. Однако curl также поддерживает объединение параметров. Например, если вы хотите загрузить файл (-O), выполнить переадресацию 301 (-L) и разрешить небезопасные сертификаты SSL (-k), вы можете использовать curl -OLk.
Основной синтаксис использования curl для загрузки файла:
Выходные данные, известные как индикатор выполнения скручивания, аналогичны следующему:
По умолчанию загружаемые файлы сохраняются в текущем рабочем каталоге. Ниже приведен сквозной визуальный пример.
Команда curl -O сохраняет файлы локально в вашем текущем рабочем каталоге, используя имя файла с удаленного сервера. Вы можете указать другое локальное имя файла и место загрузки, используя curl -o . Основной синтаксис:
Основной синтаксис:
В некоторых случаях, например при загрузке большого файла через плохое сетевое соединение, загрузка файла прерывается. Опция -C позволяет возобновить прерванную загрузку. Основной синтаксис:
Перед отображением индикатора выполнения скручивания вывод будет содержать текст, подобный следующему:
Вы можете указать несколько URL-адресов в одной команде curl, чтобы загрузить несколько файлов одной командой.
Основной синтаксис:
Счетчик выполнения curl будет отображать статистику для каждой загрузки. Для двух URL вывод будет выглядеть примерно так:
Если у вас есть длинный список URL-адресов, вы можете добавить их в текстовый файл, а затем передать curl с помощью xargs . Для демонстрации предположим, что у нас есть файл curlsites.txt, в котором наши URL-адреса размещаются в новой строке:
Теперь мы можем использовать команду xargs с curl и наш файл curlsites.txt в качестве входных данных для загрузки каждого файла:
xargs -n 1 завиток -O
Обычно curl обрабатывает URL-адреса один за другим, как и приведенный выше пример xargs. Однако вы можете добавить параметр -P к xargs для параллельной загрузки нескольких файлов. Например, эта команда запустит две загрузки curl параллельно.
xargs -P 2 -n 1 завиток -O
Для получения более подробной информации о xargs и его параметрах посетите справочную страницу xargs.
Ограничение скорости позволяет указать максимальную скорость передачи для запроса curl. Основной синтаксис для применения ограничения скорости к запросу загрузки curl:
curl --limit-rate -O
- K или k = килобайты
- M или m = мегабайты
- G или g = гигабайты
Например, чтобы установить ограничение скорости в 1000 байт в секунду для нашего примера загрузки, мы можем использовать эту команду:
Или эта команда:
Чтобы ограничить скорость до 100 мегабайт в секунду:
Обратите внимание, что curl пытается усреднить скорость передачи, чтобы не превысить значение. Когда вы впервые запускаете curl с параметром --limit-rate, вы можете увидеть скорость выше указанной, но она должна быстро выровняться.
Если сервер, с которого вы загружаете файл, работает слишком медленно, вы можете автоматически прервать соединение. Вы можете использовать параметры -Y (или --speed-limit ) и -y (или --speed-time ).
Параметр-Y (или --speed-limit ) определяет скорость (в байтах в секунду). Опция -y (или --speed-time) указывает количество времени в секундах. Если скорость загрузки меньше скорости, определенной параметром -Y, на время, определенное параметром -y, curl прервет загрузку. 30 секунд — это время по умолчанию для -Y, если -y не указано. Ниже приведены три примера для демонстрации.
Если curl прерывает загрузку из-за ограничения скорости передачи, он выводит сообщение об ошибке, подобное следующему:
Вывод индикатора выполнения будет выглядеть примерно так:
Основной синтаксис для базовой аутентификации в запросе на загрузку curl:
Вы можете подавить вывод curl с помощью параметра -s. Основной синтаксис для автоматической загрузки файла с помощью curl:
Эта команда загружает файл точно так же, как -O, но не выводит ход выполнения или статистику в стандартный вывод.
Вот основной синтаксис, позволяющий использовать небезопасные SSL-сертификаты для скачивания curl:
Если вы намеренно подключаетесь к сайту с небезопасным сертификатом TLS/SSL, параметр -k может помочь устранить такие ошибки, как:
Мы также рекомендуем посетить официальную страницу, указанную в сообщении об ошибке, для получения дополнительной информации о curl и TLS/SSL.
Поскольку для серверов FTP и SFTP часто требуется имя пользователя и пароль, в наших примерах мы будем использовать параметр -u.
Основной синтаксис загрузки по FTP с помощью curl:
Теперь, когда вы понимаете распространенные методы загрузки файлов с помощью curl в операционных системах Linux, вы можете перейти к более сложным случаям. Мы рекомендуем обращаться к официальной документации curl и бесплатной книге Everything curl для получения подробной информации о конкретных случаях использования.
Мантас Левинас
Помогаем инженерам узнавать 💡 о новых технологиях и оригинальных примерах использования автоматизации ИТ для создания более совершенных систем 💻
Присоединяйтесь к сообществу Cherry Servers
Ежемесячно получайте практические руководства по созданию более безопасных, эффективных и легко масштабируемых систем в открытой облачной экосистеме.
Читайте также: