配置FedEx贸易文件上传API遇json_encode错误,求代码排查
问题分析:FedEx贸易文件上传API触发json_encode错误
问题描述
在配置FedEx贸易文件上传API时,遇到以下错误:
json_encode error: Type is not supported
请求负载的示例代码如下:
try{ $document = [ "workflowName"=> "ETDPostshipment", "carrierCode"=> "FDXE", "name"=> 'invoiceFileName', "contentType"=> 'application/pdf', "meta"=> [ "shipDocumentType"=> "COMMERCIAL_INVOICE", "trackingNumber"=> "794988380825", "shipmentDate"=> "2024-02-26", "originCountryCode"=> "JP", "destinationCountryCode"=> $country_code ] ]; $body = [ [ 'name' => 'document', 'contents' => json_encode($document) ], [ 'name' => 'attachment', 'contents' => fopen(public_path('storage/invoice/invoiceFileName'), 'r'), 'filename' => $shipping['invoiceFileName'] ] ]; $response = $this->uploader->post($path, ['multipart' => $body]); $data = json_decode($response->getBody(), true); Log::info('Document uploaded successfully.', ['response' => $data]); return $data; } catch(RequestException $e){ Log::error('Request Exception: ' . $e->getMessage(), ['code' => $e->getCode()]); } catch (Throwable $e){ Log::error('Unexpected Exception: ' . $e->getMessage()); return; } }
错误原因
类型不兼容导致json_encode失败
错误直接触发点是json_encode($document),核心原因是$document['meta']['destinationCountryCode']对应的$country_code变量可能是非字符串类型(比如整数、未定义变量、对象),json_encode无法处理这类非预期类型的数据。文件路径与文件名不匹配
fopen中使用的固定路径public_path('storage/invoice/invoiceFileName')和参数filename的$shipping['invoiceFileName']不一致,可能导致文件无法读取。缺少文件存在性检查
未提前验证文件是否存在,若文件缺失会导致fopen返回false,进一步引发多部分请求的解析错误。
修正方案
修正后的代码
try{ $document = [ "workflowName" => "ETDPostshipment", "carrierCode" => "FDXE", "name" => 'invoiceFileName', "contentType" => 'application/pdf', "meta" => [ "shipDocumentType" => "COMMERCIAL_INVOICE", "trackingNumber" => "794988380825", "shipmentDate" => "2024-02-26", "originCountryCode" => "JP", // 强制转换为字符串,确保类型符合要求 "destinationCountryCode" => (string)$country_code ] ]; // 拼接正确的文件路径,匹配filename参数 $filePath = public_path('storage/invoice/' . $shipping['invoiceFileName']); // 提前检查文件是否存在且可读 if (!file_exists($filePath) || !is_readable($filePath)) { Log::error('Invoice file not found or unreadable: ' . $filePath); return; } // 增加json_encode错误检查 $docJson = json_encode($document); if (json_last_error() !== JSON_ERROR_NONE) { Log::error('JSON encode failed: ' . json_last_error_msg()); return; } $body = [ [ 'name' => 'document', 'contents' => $docJson ], [ 'name' => 'attachment', 'contents' => fopen($filePath, 'r'), 'filename' => $shipping['invoiceFileName'] ] ]; $response = $this->uploader->post($path, ['multipart' => $body]); $data = json_decode($response->getBody(), true); Log::info('Document uploaded successfully.', ['response' => $data]); return $data; } catch(RequestException $e){ Log::error('Request Exception: ' . $e->getMessage(), ['code' => $e->getCode()]); } catch (Throwable $e){ Log::error('Unexpected Exception: ' . $e->getMessage()); return; }
额外检查项
- 确认
$country_code变量已正确赋值,且为ISO 3166-1 alpha-2格式的字符串(如"US"、"CN") - 确保PHP进程拥有目标文件的读取权限
- 若使用Guzzle作为HTTP客户端,可手动关闭文件资源避免内存泄漏(Guzzle通常会自动处理)
内容的提问来源于stack exchange,提问作者Bipu Shrestha
相关产品推荐
相关产品推荐

