Решение ошибки "Bad Request: there is no document in the request" при отправке файла в Telegram API

    При отправке документа через Telegram Bot API возникает следующая ситуация: код корректно работает на хостинге, но при запуске через 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);

    Причина ошибки

    Проблема заключается в некорректной передаче данных в параметре CURLOPT_POSTFIELDS. При использовании json_encode() для массива, содержащего объект CURLFile, сериализация происходит неправильно, особенно в среде OpenServer.

    Решение

    Для корректной отправки файла через cURL необходимо передавать данные в формате массива без преобразования в JSON. Telegram API ожидает данные в формате multipart/form-data, который cURL формирует автоматически при передаче массива или строки с постфиксом @.

    Замените строку с CURLOPT_POSTFIELDS на следующую:

    CURLOPT_POSTFIELDS      => array(
        'chat_id' => $CHAT_ID,
        'document' => new \CURLFile($FILE)
    ),

    Уберите вызов json_encode(). cURL самостоятельно установит правильный заголовок Content-Type: multipart/form-data и корректно обработает файл.

    Исправленный код

    $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      => array(
            'chat_id' => $CHAT_ID,
            'document' => new \CURLFile($FILE)
        ),
    ));
    echo curl_exec($ch);
    curl_close($ch);

    После этого изменения код будет стабильно работать как на хостинге, так и в локальном окружении OpenServer.