Как отправить файл в Telegram бот на OpenServer PHP cURL
Решение ошибки 'Bad Request: there is no document' в telegram бот на openserver php. Правильный код cURL без json_encode для sendDocument, настройка CURLFile, пути и отладка. Работает на OpenServer 6.5.0.
Как отправить файл в 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
)
Код:
$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”
- Правильный код PHP cURL для telegram bot api sendDocument без json_encode
- Настройка пути к файлу и CURLFile на openserver php
- Telegram curl примеры: multipart/form-data vs JSON
- Отладка ошибок telegram bot php на локальном сервере OpenServer
- Альтернативы: webhook и библиотеки для telegram bot api php
- Источники
- Заключение
Почему 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
$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 для надёжности.
Добавьте в код:
$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 — для файлов.
Неправильно (ваш вариант):
curl -X POST https://api.telegram.org/botTOKEN/sendDocument \
-d '{"chat_id":"ID","document":"{\"@type\":\"CURLFile\"...}"}' # Строка! Ошибка
Правильно (CLI-аналог для теста):
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
Не сработало? Отлаживаем шаг за шагом.
-
Проверьте ответ:
$response = curl_exec($ch); $info = curl_getinfo($ch); var_dump($info, json_decode($response, true));— увидите HTTP 400/200, ошибки. -
Логи cURL:
curl_setopt($ch, CURLOPT_VERBOSE, true); $verbose = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $verbose);— rewind($verbose) и fread покажет сырой запрос. -
OpenServer логи: В панели → Журнал → PHP error log. Ищите “file not found” или curl warnings.
-
Тест без файла: Отправьте текст —
sendMessage. Если ок, проблема в CURLFile. -
Версия 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.
Источники
- Telegram Bot API — Документация метода sendDocument для отправки файлов: https://core.telegram.org/bots/api#senddocument
- Stack Overflow — Отправка файла через CURL в Telegram Bot API без ошибок: https://stackoverflow.com/questions/33853502/posting-a-file-via-curl-to-the-telegram-bot-api
- Stack Overflow — Решение sendDocument на хостинге и локалке с PHP: https://stackoverflow.com/questions/66244747/telegram-bot-senddocument-php-on-hosted-server
- PHP.net — Справочник по curl_setopt и работе с CURLFile в multipart: https://www.php.net/manual/en/function.curl-setopt.php
Заключение
Теперь telegram бот на openserver php шлёт файлы без сбоев — ключ в отказе от json_encode и проверке путей. Протестируйте код, добавьте отладку, и вы в деле. Если масштабируете, переходите на библиотеки или webhook — проще жизнь. Удачи с ботом!
Ошибка 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)для указания типа.
Для 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).
В Telegram Bot API PHP передавайте new CURLFile(realpath('file.jpg')) в массив CURLOPT_POSTFIELDS с 'chat_id'. Не задавайте Content-Type — cURL сам сделает multipart/form-data. Для Telegram не отправляет файлы на OpenServer PHP проверьте realpath и var_dump результата curl_exec. Filename опционально, Telegram Bot cURL определит сам. Удаляйте файл после отправки, если временный.
Дополнительно:
- Добавьте
CURLOPT_VERBOSE => trueдля отладки. - Используйте
curl_getinfo($ch)для проверки HTTP-кода.
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.