Как в Guzzle отправить multipart запрос с дополнительными полями

Допустим есть задача — отправить HTTP-запрос с бинарным файлом на сторонний сервис. Рассмотрим решения на примере клиентской библиотеки Guzzle.

$client->request('POST', '/post', [
    'multipart' => [
        [
            'name'     => 'avatarka.jpg',
            'contents' => fopen('/path/to/file', 'r'),
            'filename' => 'custom_filename.jpg'
        ],
    ]
]);

Окей, а что если нужно оправить дополнительные значения, например, имя пользователя. Существует 2 способа решения. Первый — прокидывание дополнительных полей через заголовки:

'multipart' => [
        [
            'name'     => 'avatarka.jpg',
            'contents' => fopen('/path/to/file', 'r'),
            'filename' => 'custom_filename.jpg',
            'headers'  => ['X-Username' => 'Gavrilo']
        ],
    ]

А второй вариант, использование массива multipart значений:

'multipart' => [
        [
            'name'     => 'avatarka.jpg',
            'contents' => fopen('/path/to/file', 'r'),
            'filename' => 'custom_filename.jpg'
        ],
        [
            'name'     => 'username',
            'contents' => 'Gavrilo' ]
    ]

И только так. А теперь приведу объяснения из документации Guzzle. Массив multipart устанавливает тело запроса в форму multipart / form-data. Каждый элемент может содержать следующие значения:

  • name: (string, required) имя поля формы
  • contents: (StreamInterface/resource/string, required) значение поля
  • headers: (array) Необязательный ассоциативный массив пользовательских заголовков
  • filename: (string) Необязательная строка для отправки в качестве имени файла

При этом multipart не может использоваться одновременно с опцией form_params или json. Используйте form_params для запросов application/x-www-form-urlencoded, а multipart для запросов multipart/form-data.

Подробнее смотрите здесь: http://docs.guzzlephp.org/en/stable/request-options.html