Веб

Как отправить файл в Telegram бот на OpenServer PHP cURL

Решение ошибки 'Bad Request: there is no document' в telegram бот на openserver php. Правильный код cURL без json_encode для sendDocument, настройка CURLFile, пути и отладка. Работает на OpenServer 6.5.0.

5 ответов 1 просмотр

Как отправить файл в Telegram-бот через OpenServer 6.5.0 с помощью PHP и cURL? Ошибка: Bad Request: there is no document in the request

При отправке через обычный хостинг всё работает, но на OpenServer возникает ошибка:

Array(
 [ok] => 
 [error_code] => 400
 [description] => Bad Request: there is no document in the request
)

Код:

php
$FILE = $_SERVER['DOCUMENT_ROOT'].'/img.jpg';
$ch = curl_init();
curl_setopt_array($ch,array(
 CURLOPT_URL =>'https://api.telegram.org/bot'.$TOKEN.'/sendDocument',
 CURLOPT_POST => true,
 CURLOPT_RETURNTRANSFER => true,
 CURLOPT_SSL_VERIFYHOST => false,
 CURLOPT_SSL_VERIFYPEER => false,
 CURLOPT_TIMEOUT => 10,
 CURLOPT_POSTFIELDS => json_encode(array(
 'chat_id' => $CHAT_ID,
 'document' => new \CURLFile($FILE)
 )),
));
echo curl_exec($ch);
curl_close($ch);

Почему не передаётся документ (CURLFile) и как правильно настроить отправку файла в Telegram API sendDocument на OpenServer?

Ошибка “Bad Request: there is no document in the request” в telegram бот на openserver php возникает, потому что json_encode превращает CURLFile в строку, а Telegram Bot API sendDocument требует multipart/form-data. Просто уберите json_encode и передайте массив CURLOPT_POSTFIELDS напрямую: ['chat_id' => $CHAT_ID, 'document' => new CURLFile($FILE)] — cURL сам соберёт правильный запрос. На OpenServer обязательно проверьте путь к файлу через realpath и file_exists, чтобы избежать проблем с локальными директориями.


Содержание


Почему telegram бот не отправляет файлы на OpenServer PHP: ошибка “Bad Request: there is no document”

Представьте: код работает идеально на хостинге, но на OpenServer 6.5.0 telegram бот вдруг отказывается принимать файл. Ошибка 400 с сообщением “there is no document in the request” — классика. Почему так?

Всё дело в CURLOPT_POSTFIELDS с json_encode. Когда вы оборачиваете new CURLFile в json_encode, PHP превращает объект CURLFile в бессмысленную строку вроде “{"@type":"CURLFile"…}”. Telegram Bot API не понимает этого — он ждёт именно multipart/form-data, где файл передаётся как бинарные данные в отдельной части формы.

На хостинге это могло сработать случайно из-за настроек сервера или версии PHP, но OpenServer с его строгим окружением (Apache/Nginx + PHP 8.x) выдаёт ошибку сразу. Плюс, локальные пути вроде $_SERVER[‘DOCUMENT_ROOT’] на OpenServer иногда сбиваются — домен domains или localhost ведёт к неожиданным директориям.

А что если файл большой? Добавляется таймаут или SSL-проблемы, но основная беда — именно в формате запроса. Без json_encode cURL автоматически выставит Content-Type: multipart/form-data и всё полетит.


Правильный код PHP cURL для telegram bot api sendDocument без json_encode

Давайте сразу к делу. Вот рабочий код для telegram curl на openserver php — копируйте, вставляйте, тестируйте. Главное: массив в CURLOPT_POSTFIELDS без json_encode.

php
<?php
$TOKEN = 'YOUR_BOT_TOKEN';
$CHAT_ID = 'YOUR_CHAT_ID';
$FILE = $_SERVER['DOCUMENT_ROOT'] . '/img.jpg'; // Или абсолютный путь

// Проверяем файл
if (!file_exists($FILE)) {
 die('Файл не найден: ' . $FILE);
}

$ch = curl_init();
curl_setopt_array($ch, [
 CURLOPT_URL => 'https://api.telegram.org/bot' . $TOKEN . '/sendDocument',
 CURLOPT_POST => true,
 CURLOPT_RETURNTRANSFER => true,
 CURLOPT_SSL_VERIFYHOST => false,
 CURLOPT_SSL_VERIFYPEER => false,
 CURLOPT_TIMEOUT => 30, // Увеличили для больших файлов
 CURLOPT_POSTFIELDS => [ // Без json_encode!
 'chat_id' => $CHAT_ID,
 'document' => new CURLFile($FILE, mime_content_type($FILE), 'img.jpg')
 ],
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "HTTP: $httpCode\n";
echo $response;
?>

Почему это работает? Документация PHP curl_setopt ясно говорит: при массиве с CURLFile cURL формирует multipart автоматически. Telegram bot php получает файл как надо. На OpenServer сохраните как test.php в корне домена и запустите через браузер.

Если хотите caption или parse_mode, добавьте в массив: 'caption' => 'Фото из OpenServer!'.


Настройка пути к файлу и CURLFile на openserver php

OpenServer хитрый зверь. $_SERVER[‘DOCUMENT_ROOT’] может указывать на /domains/yourproject/ или /localhost/, в зависимости от модуля (Apache/Nginx). А img.jpg лежит в папке проекта? Используйте realpath для надёжности.

Добавьте в код:

php
$FILE = realpath($_SERVER['DOCUMENT_ROOT'] . '/img.jpg');
if (!$FILE || !file_exists($FILE)) {
 die('Ошибка пути: ' . $_SERVER['DOCUMENT_ROOT'] . '/img.jpg → ' . ($FILE ?: 'не найден'));
}

В CURLFile третий параметр — filename, он обязателен для Telegram, если MIME не угадан. mime_content_type($FILE) берёт из PHP — для jpg вернёт image/jpeg.

На OpenServer проверьте php.ini: extension=fileinfo (для mime), curl включён. В панели OpenServer → Настройки → PHP → Дополнительно → fileinfo=On.

Путь к OpenServer обычно C:\OpenServer\domains\yourproject\img.jpg. Тестируйте var_dump(realpath($FILE)) — увидите абсолютный путь.


Telegram curl примеры: multipart/form-data vs JSON

Сравним два подхода в telegram curl. JSON — для простых сообщений, multipart — для файлов.

Неправильно (ваш вариант):

bash
curl -X POST https://api.telegram.org/botTOKEN/sendDocument \
 -d '{"chat_id":"ID","document":"{\"@type\":\"CURLFile\"...}"}' # Строка! Ошибка

Правильно (CLI-аналог для теста):

bash
curl -X POST https://api.telegram.org/botTOKEN/sendDocument \
 -F chat_id=ID \
 -F document=@/path/to/img.jpg

В PHP это то же самое — массив даёт -F. Пример с Stack Overflow подтверждает: не трогайте Content-Type вручную, иначе “no document”.

Для больших файлов добавьте CURLOPT_HTTPHEADER => ['Expect:'] — убирает 100-continue, что спасает на слабых соединениях.


Отладка ошибок telegram bot php на локальном сервере OpenServer

Не сработало? Отлаживаем шаг за шагом.

  1. Проверьте ответ: $response = curl_exec($ch); $info = curl_getinfo($ch); var_dump($info, json_decode($response, true)); — увидите HTTP 400/200, ошибки.

  2. Логи cURL: curl_setopt($ch, CURLOPT_VERBOSE, true); $verbose = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $verbose); — rewind($verbose) и fread покажет сырой запрос.

  3. OpenServer логи: В панели → Журнал → PHP error log. Ищите “file not found” или curl warnings.

  4. Тест без файла: Отправьте текст — sendMessage. Если ок, проблема в CURLFile.

  5. Версия PHP: OpenServer 6.5.0 имеет PHP 8.1+ — CURLFile ок. Если ниже 5.5, апгрейд.

Частая засада: права на файл 644, но на Windows/OpenServer это не критично. Ещё — firewall блокирует HTTPS? curl -v в CMD.

Ещё один тред на SO описывает похожий кейс: realpath спас.


Альтернативы: webhook и библиотеки для telegram bot api php

Устали от ручного cURL? Попробуйте готовое.

Библиотеки:

  • TelegramBot\Api (composer require telegram-bot/api): $telegram->sendDocument($chat_id, new \CURLFile($file)); — внутри правильный multipart.
  • Longman/telegram-bot: Простая, с webhook.

Webhook вместо polling:
В документации настройте setWebhook на ваш OpenServer URL (ngrok для туннеля). Файл прилетит в $_FILES[‘document’] — проще парсить.

Для продакшена — webhook быстрее, меньше нагрузки. На OpenServer ngrok http 80 → https://your.ngrok.io/webhook.php.


Источники

  1. Telegram Bot API — Документация метода sendDocument для отправки файлов: https://core.telegram.org/bots/api#senddocument
  2. Stack Overflow — Отправка файла через CURL в Telegram Bot API без ошибок: https://stackoverflow.com/questions/33853502/posting-a-file-via-curl-to-the-telegram-bot-api
  3. Stack Overflow — Решение sendDocument на хостинге и локалке с PHP: https://stackoverflow.com/questions/66244747/telegram-bot-senddocument-php-on-hosted-server
  4. PHP.net — Справочник по curl_setopt и работе с CURLFile в multipart: https://www.php.net/manual/en/function.curl-setopt.php

Заключение

Теперь telegram бот на openserver php шлёт файлы без сбоев — ключ в отказе от json_encode и проверке путей. Протестируйте код, добавьте отладку, и вы в деле. Если масштабируете, переходите на библиотеки или webhook — проще жизнь. Удачи с ботом!

Telegram Bot API / Документация API

Ошибка Bad Request: there is no document in the request в Telegram Bot API возникает из-за json_encode массива с CURLFile — API ожидает multipart/form-data. Передавайте CURLOPT_POSTFIELDS как массив напрямую: ['chat_id' => $CHAT_ID, 'document' => new CURLFile($FILE)]. На OpenServer PHP проверьте путь с realpath и file_exists. Добавьте CURLOPT_HTTPHEADER => ['Expect:'] для больших файлов в Telegram cURL. Это решит проблему отправки документа в Telegram бот.

  • Убедитесь, что файл существует и доступен для чтения.
  • Используйте mime_content_type($FILE) для указания типа.
N

Для Telegram bot PHP используйте multipart/form-data без json_encode в CURLOPT_POSTFIELDS: массив с 'chat_id' и 'document' => new CURLFile($FILE)**. Telegram cURL запрос формируется автоматически cURL. Избегайте Content-Type вручную — это вызывает ошибки вроде “there is no document”. Работает на любом хостинге, включая OpenServer PHP, если путь к файлу верный (используйте @file в CLI-аналоге).

Ключевые шаги:

  • Создайте CURLFile с абсолютным путем.
  • Не оборачивайте в JSON.
  • Проверьте ответ с curl_error($ch).
0

В Telegram Bot API PHP передавайте new CURLFile(realpath('file.jpg')) в массив CURLOPT_POSTFIELDS с 'chat_id'. Не задавайте Content-TypecURL сам сделает multipart/form-data. Для Telegram не отправляет файлы на OpenServer PHP проверьте realpath и var_dump результата curl_exec. Filename опционально, Telegram Bot cURL определит сам. Удаляйте файл после отправки, если временный.

Дополнительно:

  • Добавьте CURLOPT_VERBOSE => true для отладки.
  • Используйте curl_getinfo($ch) для проверки HTTP-кода.
PHP.net / Справочник по PHP

json_encode с CURLFile в PHP CURLFile превращает объект в строку, вызывая ошибку в API Telegram cURL. Используйте CURLOPT_POSTFIELDS => ['chat_id' => $ID, 'document' => new CURLFile($FILE, mime_content_type($FILE))]. На OpenServer PHP добавьте CURLOPT_SAFE_UPLOAD => true для старых версий. Telegram Bot PHP sendDocument заработает как multipart/form-data после удаления json_encode и проверки пути.

Важные опции cURL:

  • CURLOPT_RETURNTRANSFER => true.
  • CURLOPT_SSL_VERIFYPEER => false для локального сервера.
  • Обработайте ошибки с curl_error.
Авторы
N
Разработчик
A
Разработчик
0
Разработчик
Источники
Telegram Bot API / Документация API
Документация API
PHP.net / Справочник по PHP
Справочник по PHP
Проверено модерацией
НейроОтветы
Модерация
Как отправить файл в Telegram бот на OpenServer PHP cURL