Отправка и получение файлов с помощью cURL в PHP

Раздел: PHP -> HTTP запросы с cURL

Работа с файлами через cURL в PHP

Наиболее эффективное решение: использование CURLFile (PHP 5.5+)

Для отправки файла на сервер через POST-запрос рекомендуется применять класс CURLFile. Он корректно формирует multipart/form-data, автоматически определяет MIME-тип и имя файла. Пример:


$ch = curl_init('https://example.com/upload.php');
$file = new CURLFile('/path/to/document.pdf', 'application/pdf', 'document.pdf');
$data = ['file' => $file];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

Php curl timeout (php curl таймаут)

Пояснение шагов:

  • Создаётся экземпляр CURLFile с абсолютным путём, MIME-типом и именем для отправки.
  • Файл добавляется в ассоциативный массив $data как значение поля file.
  • Опция CURLOPT_POST включает метод POST.
  • Массив передаётся в CURLOPT_POSTFIELDS – cURL автоматически кодирует его как multipart/form-data.
  • Ответ сервера сохраняется в $response.

Возможные проблемы:

  • Ошибка curl error: 26 – файл не найден. Проверить путь и права доступа.
  • Ошибка 413 Request Entity Too Large – превышен лимит сервера. Увеличить post_max_size и upload_max_filesize в PHP или на стороне сервера.
  • Неправильный MIME-тип может вызвать отказ на принимающей стороне. Использовать mime_content_type() для определения.

Как отправить файл из строки (без временного файла)?

Иногда требуется передать динамически сгенерированное содержимое. Используется CURLFile с псевдо-путем php://temp или php://memory, но проще создать временный файл через tmpfile():


$temp = tmpfile();
fwrite($temp, 'содержимое файла');
$meta = stream_get_meta_data($temp);
$path = $meta['uri'];
$file = new CURLFile($path, 'text/plain', 'data.txt');
$data = ['upload' => $file];
// ... cURL запрос ...
fclose($temp);

Php curl ssl (php curl ssl)

Важно закрыть временный файл после запроса. Если несколько потоков, использовать curl_file_create() (псевдоним).

Как скачать файл с сервера и сохранить на диск?

Для загрузки файла используется опция CURLOPT_FILE, куда передаётся открытый файловый дескриптор:


$ch = curl_init('https://example.com/image.jpg');
$fp = fopen('/local/path/image.jpg', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
fclose($fp);
curl_close($ch);

Php curl ответ (ответ php curl)

Пояснения: флаг 'wb' открывает файл для бинарной записи. При ошибке записи fopen вернёт false.

Типичная ошибка: забыть закрыть дескриптор до завершения скрипта. Использовать try-finally или CURLOPT_RETURNTRANSFER с последующей записью.

Как отправить несколько файлов одновременно?

Массив значений может содержать несколько CURLFile объектов с разными ключами:


$files = [
    'photo1' => new CURLFile('/path/1.jpg', 'image/jpeg', '1.jpg'),
    'photo2' => new CURLFile('/path/2.png', 'image/png', '2.png'),
];
$data = array_merge(['token' => 'abc'], $files);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

Php curl authorization (php curl авторизация)

Если нужно отправить массив файлов с одним именем поля, используйте суффикс [] в ключе:


$files = [
    new CURLFile(...),
    new CURLFile(...),
];
$data = ['photos' => $files]; // префикс 'photos' будет преобразован в 'photos[0]', 'photos[1]'

Php curl close (php curl close)

Некоторые серверы требуют строгий формат именования. Тестировать с реальным API.

Как работать с очень большими файлами (избежать нехватки памяти)?

Для передачи больших данных (сотни мегабайт) используется потоковая передача через CURLOPT_INFILE и CURLOPT_INFILESIZE:


$fp = fopen('/path/to/largefile.iso', 'rb');
$ch = curl_init('https://upload.example.com/');
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize('/path/to/largefile.iso'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
fclose($fp);
curl_close($ch);

Php curl cookie (php curl cookie)

При использовании CURLOPT_PUT данные читаются из потока. Для POST с multipart лучше разбивать файл на части.

Проблема: сервер может не поддерживать PUT. Альтернатива – читать файл блоками и отправлять multipart вручную через CURLOPT_READFUNCTION.

Как получить содержимое файла в переменную, а не на диск?

Установка CURLOPT_RETURNTRANSFER в true возвращает данные как строку:


curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
file_put_contents('downloaded.pdf', $content);

Php curl url (php curl url)

Это удобно для маленьких файлов, но для больших может занять всю память. Рекомендовать для файлов до 20-30 МБ.

Ошибка Cannot allocate memory при слишком больших объёмах. Использовать потоковую запись.

Как отправить файл вместе с текстовыми полями формы?

Достаточно добавить поля в тот же массив $data. cURL автоматически смешает multipart и urlencoded:


$data = [
    'name' => 'John',
    'avatar' => new CURLFile('avatar.png', 'image/png'),
];
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

Важно: текстовые поля должны быть строковыми, файлы – объектами CURLFile.

Если текстовое поле содержит символы вне ASCII, может возникнуть кодировка. Использовать urlencode не нужно – cURL обработает сам.

- Php curl file (php curl файл)
- Php curl html (php curl html)
- Php curl content (содержимое ответа php curl)

Расширенные примеры работы с файлами через cURL

Пример 1. Загрузка файла с индикатором прогресса

Функция CURLOPT_PROGRESSFUNCTION позволяет отслеживать передачу данных. Пример для отправки большого файла:

Пример

$file = new CURLFile('video.mp4', 'video/mp4');
$ch = curl_init('https://upload.endpoint');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => $file]);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function($ch, $downloadSize, $downloaded, $uploadSize, $uploaded) {
    if ($uploadSize > 0) {
        echo "Передано: " . round($uploaded / $uploadSize * 100, 2) . "%\n";
    }
});
curl_exec($ch);
curl_close($ch);

Результат: в консоли выводятся проценты загрузки. Важно: функция вызываеться часто, не рекомендуется использовать ресурсоёмкие операции.

Пример 2. Множественная загрузка файлов с помощью curl_multi

Асинхронная отправка нескольких файлов повышает скорость. Используем curl_multi_init():

Пример

$files = [
    'doc1.pdf' => ['path' => '/tmp/doc1.pdf', 'mime' => 'application/pdf'],
    'img.png'  => ['path' => '/tmp/img.png', 'mime' => 'image/png'],
];
$mh = curl_multi_init();
$handles = [];
foreach ($files as $name => $info) {
    $ch = curl_init('https://api.example.com/upload');
    $file = new CURLFile($info['path'], $info['mime'], $name);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => $file]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $ch);
    $handles[] = $ch;
}
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);
foreach ($handles as $ch) {
    echo curl_multi_getcontent($ch) . "\n";
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);

Результат: ответ сервера для каждого файла выводится на экран. curl_multi работает асинхронно, но блокируется на curl_multi_select.

Пример 3. Отправка файла через FTP с cURL

cURL поддерживает протокол FTP. Загрузка файла на FTP-сервер:

Пример

$ch = curl_init('ftp://user:password@ftp.example.com/remote/file.pdf');
$fp = fopen('/local/file.pdf', 'rb');
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize('/local/file.pdf'));
curl_exec($ch);
fclose($fp);
curl_close($ch);

Для пассивного режима добавить CURLOPT_FTP_USE_EPSV, true. При ошибке авторизации проверить логин/пароль в URL.

Пример 4. Получение файла с сервера и сохранение с именем из заголовков

Некоторые серверы возвращают имя файла в заголовке Content-Disposition. Извлечение:

Пример

$ch = curl_init('https://example.com/download.php?id=123');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
// Парсим Content-Disposition
preg_match('/Content-Disposition:.*?filename="(.+?)"/', $header, $matches);
$filename = $matches[1] ?? 'downloaded_file';
file_put_contents($filename, $body);
curl_close($ch);

Результат: файл сохраняется с оригинальным именем. Обратите внимание на экранирование кавычек в регулярном выражении.

Пример 5. Отправка файла через PUT-запрос (простой)

PUT-метод часто используется для обновления ресурса. Пример с чтением потока:

Пример

$ch = curl_init('https://api.example.com/files/123');
$fp = fopen('new_data.bin', 'rb');
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize('new_data.bin'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
fclose($fp);
curl_close($ch);
echo $response;

Результат – ответ сервера (например, статус 200/201).

Пример 6. Скачивание файла с игнорированием SSL-ошибок (не рекомендуется)

Для тестовых серверов можно отключить проверку SSL:

Пример

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

Результат: соединение происходит без проверки сертификата. В продукции обязательно настроить CURLOPT_CAINFO.

Пример 7. Отправка файла с использованием CURLOPT_READFUNCTION

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

Пример

$ch = curl_init('https://api.example.com/upload');
$data = 'some binary content'; // допустим, 1 МБ
$size = strlen($data);
$offset = 0;
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $stream, &$maxlen) use ($data, $size, &$offset) {
    $remaining = $size - $offset;
    $chunk = min($remaining, $maxlen);
    $result = substr($data, $offset, $chunk);
    $offset += $chunk;
    return $result;
});
curl_setopt($ch, CURLOPT_INFILESIZE, $size);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

Результат: данные передаются без копирования в файл. Полезно для больших объёмов, когда содержимое генерируется на лету.

PHP cURL файл - comments

En
Php curl file (php)