chazovs
@chazovs
Корпорация Центр

Как отправить multipart/form-data в Nyholm\Psr7?

Задача: отправить файл с помощью Nyholm/Psr7. Как понятно из названия, библиотека поддерживает PSR7. Я пробую сделать так:
$fileStream = $this->requestFactory->createStream('Привет мир');
            $uploadFile = $this->requestFactory->createUploadedFile($fileStream, clientFilename: 'document');

            $uriString = $this->url . '/' . $endpoint . '?' . http_build_query($query);
            $uriObject = $this->requestFactory->createUri($uriString);

           $request = $this->requestFactory->createRequest(Request::METHOD_POST, $uriObject)
            ->withHeader('Content-Type', $contentType)
            ->withBody($uploadFile->getStream())
        ;


requestFactory - это Nyholm\Psr7\Factory\Psr17Factory

Как правильно это делать?
  • Вопрос задан
  • 113 просмотров
Пригласить эксперта
Ответы на вопрос 2
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
Эм, вы что-то напутали.

'multipart/form-data' - это формат запроса. Вы от клиента присылаете его на сервер.

Отдавать 'multipart/form-data' это как просить сервер заполнить форму на компьютере пользователя.

Там нет формы.

То есть сам паттерн Psr7 это не про "сделай запрос куда-то". Это "разбери $_GET/$_POST/$_FILES" так, чтобы получились стандартные ServerRequestInterface с которыми потом работает приложение. То есть "создать на сервере multipart/form-data $request" будет что-то примерно ::createFromGlobals() без параметров, и оно само его создаст, если вы отправите на сервер форму.

Создавать псевдо-реквест с мультипарт-формдата, не получив с клиента запрос с этим заголовком, может быть нужно было только самим разрабам библиотеки когда они её тестировали.

Чтобы ваша задача стала реальностью её текст должен звучать примерно так: "Клиент с сайта отправляет слово `привет`, а я на сервере в этот момент подменяю слово на файл с именем `привет.txt` и делаю вид будто юзер отправил мне файл." Если вы хотите клиенту файл отдать - то это Content-Disposition: attachment, а не Content-Type: multipart/form-data.

Если вы хотите отправить запрос - вам нужно использовать GuzzleHttp или curl, а не ServerRequestFactory, то есть Psr7 - это парсер входящего реквеста, а не генератор хттп запросов куда-то. Технически как-то можно их приравнять... но что получится вы уже видели.
Ответ написан
Комментировать
chazovs
@chazovs Автор вопроса
Корпорация Центр
Я понимаю, что фабрика запросов, никуда их сама не отправляет) Саму отправку я пытаюсь сделать с помощью Psr18Client. Я просто опустил эту строку. Вот она:
$this->client->sendRequest($request);

Я пытаюсь отправить файл в телеграм вот этим способом https://core.telegram.org/bots/api#senddocument
Я знаю, как это сделать через curl:
curl --location --request POST 'https://api.telegram.org/botX?chat_id=X&text=тестовое сообщение&parse_mode=markdown' \
--header 'Content-Type: multipart/form-data' \
--form 'document=@"/какой-то путь/test.txt"'

Это работает из Postman. 62fb289181596955805239.png

Но как повторить это в коде? Нашел какой-то createServerRequest. Возвращает ServerRequestInterface у которого есть метод withUploadedFiles. Но это пока тоже не работает.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы