*** Обновлено:
Я использую 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
и экземпляр CURLFile для file
.
Возможно, вам действительно нужно отправить фактическое содержимое файла в строковой форме, в документации в качестве типа параметра указан string <file>
. Не знаю, почему они настаивают на том, чтобы это был запрос multipart/form-data
, если фактическая загрузка HTTP-файла не выполняется.
Вы были правы: документ должен был быть CURLFile. Моя проблема была в структуре отправленного сообщения. В документации была ошибка, которая сбила меня с пути.
Соответствующий 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)
];
Спасибо за вашу помощь. К сожалению, я все еще получаю сообщение «Неверные данные документа».
Как обнаружил @Emtek, настоящая проблема заключается в том, что документация по API FedEx неверна.
document
и элемент rules
находятся на одном уровне.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',
]
];
Здесь вы кодируете весь свой запрос как JSON, но только содержимое
document
должно быть JSON. И то, как вы создаете параметр $file, тоже неверно. Предполагается, что это обычная загрузка файла по HTTP — поэтому используйте для этого классCURLFile
.