Как передать параметр «attachment» apiRequest для загрузки изображения FedEx?

*** Обновлено:

Я использую FedEx REST API для загрузки изображений (/documents/v1/lhsimages/upload) и получаю сообщение об ошибке:

    [errors] => stdClass Object
        (
            [code] => 1001
            [message] => Invalid request: invalid input : Invalid document details
        )

Я подозреваю, что проблема может быть связана с тем, как я передаю данные - обычно вы это делаете в запросе cURL для API FedEx.

         curl_setopt($ch, CURLOPT_POSTFIELDS, $this->apiRequest);

где $this->apiRequest — тело запроса в формате JSON. Это работает для других запросов API. Но загрузить изображение немного сложнее, поскольку оно содержит данные поля и файл:

document: {"document": {"referenceId": "1234", "name": "LH2.PNG",    "contentType": "image/png",    "meta": { "imageType": "SIGNATURE","imageIndex": "IMAGE_1"}},"rules": {"workflowName": "LetterheadSignature" }}
attachment: file.PNG

То, что я проходил, было

        $body = (object)[
            'referenceId' => 'Signature',
            'name' => $filename,
            'contentType' => $filetype,
            'rules' => (object)[
               'workflowName' => 'LetterheadSignature',
            ],
            'meta' => (object)[
               'imageType' => 'SIGNATURE',
               'imageIndex' => 'IMAGE_1',
            ]
        ];

         $sent_data = [
            'document' => json_encode($body),
            'attachment' => $file,
         ];

         $this->apiRequest = $sent_data;

Я пробовал построить параметр $file двумя способами:

      $handle = fopen($full_filename, "r");
      $file_contents = fread($handle, filesize($full_filename));
      fclose($handle);
      $file = base64_encode($file_contents);

а также:

      $file = curl_file_create($full_filename, $filetype, $filename);

где

      $filename = 'image-of-signature.png';
      $filetype = 'image/png';
      $full_filename = 'path-to-file' . $filename;

Ни то, ни другое не сработало; оба выдали мне ошибку Invalid request: invalid input : Invalid document details 1001.

Документация FedEx описывает параметр attachment как:

string <file>
Input the actual document/file to be uploaded.

Я также попытался передать реальный путь к файлу, и, конечно, это тоже не сработало.

Здесь вы кодируете весь свой запрос как JSON, но только содержимое document должно быть JSON. И то, как вы создаете параметр $file, тоже неверно. Предполагается, что это обычная загрузка файла по HTTP — поэтому используйте для этого класс CURLFile.

CBroe 11.07.2024 12:24

Да, JSON для параметра document и экземпляр CURLFile для file.

CBroe 11.07.2024 13:37

Возможно, вам действительно нужно отправить фактическое содержимое файла в строковой форме, в документации в качестве типа параметра указан string <file>. Не знаю, почему они настаивают на том, чтобы это был запрос multipart/form-data, если фактическая загрузка HTTP-файла не выполняется.

CBroe 11.07.2024 13:51

Вы были правы: документ должен был быть CURLFile. Моя проблема была в структуре отправленного сообщения. В документации была ошибка, которая сбила меня с пути.

Scott C Wilson 15.07.2024 14:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
92
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Соответствующий open-api-json

{
  "requestBody": {
    "content": {
      "multipart/form-data": {
        "schema": {"$ref": "#/components/schemas/FullSchema-ImageUploadServiceInputVO"},
        "examples": {
          "Full-Schema": {"value": "document: {\"document\": {\"referenceId\": \"1234\", \"name\": \"LH2.PNG\",    \"contentType\": \"image/png\",    \"meta\": { \"imageType\": \"SIGNATURE\",\"imageIndex\": \"IMAGE_1\"}},\"rules\": {\"workflowName\": \"LetterheadSignature\" }}\nattachment: file.PNG"}
        }
      }
    }
  }
}

Так что, возможно, добавьте этот вариант завитка:

CURLOPT_HTTPHEADER => array(
    'Content-Type: multipart/form-data'
  )

//И создаем приложение следующим образом:

$sent_data = [
            'document' => json_encode($body),
            'attachment' => new CURLFILE($full_filename)
         ];

Спасибо за вашу помощь. К сожалению, я все еще получаю сообщение «Неверные данные документа».

Scott C Wilson 12.07.2024 11:19

Как обнаружил @Emtek, настоящая проблема заключается в том, что документация по API FedEx неверна.

  1. Элемент document и элемент rules находятся на одном уровне.
  2. document — это и индекс массива в данных POST, и имя части данных в формате json_encoded. Правильная структура body:
      $body = (object)[
         'document' => (object)[
            'referenceId' => 'Letterhead',
            'name' => $filename,
            'contentType' => $filetype,
            'meta' => (object)[
               'imageType' => 'LETTERHEAD',
               'imageIndex' => 'IMAGE_2',
            ],
         ],
         'rules' => (object)[
            'workflowName' => 'LetterheadSignature',
         ]
      ];

Тогда ты делаешь

         $sent_data = [
            'document' => json_encode($body),
            'attachment' => $file,
         ];

         $this->apiRequest = $sent_data;

Если вы не сделаете все это, вы получите ошибку 1001:

        "message": "Invalid request: invalid input : Invalid document details"

или

        "message": "Invalid request: invalid input : WorkFlow Name"

Первым человеком, который указал на то, что позиция rules в документации неверна, был @Emtek в этом посте: https://stackoverflow.com/a/78697033

Ответ принят как подходящий

В отличие от того, что показано в документации FedEx API, элементы document и rules находятся на одном уровне. Правильная структура body:

      $body = (object)[
         'document' => (object)[
            'referenceId' => 'Letterhead',
            'name' => $filename,
            'contentType' => $filetype,
            'meta' => (object)[
               'imageType' => 'LETTERHEAD',
               'imageIndex' => 'IMAGE_2',
            ],
         ],
         'rules' => (object)[
            'workflowName' => 'LetterheadSignature',
         ]
      ];

Другие вопросы по теме