PHP调用FedEx费率API返回乱码问题求助
问题描述
已成功获取FedEx费率与运输时间API的Bearer Token,但请求货物费率接口时返回随机乱码,无任何错误提示。
现有代码
主脚本
ini_set('display_errors', 1); error_reporting(-1); $access_url = 'https://apis-sandbox.fedex.com/oauth/token'; $access_headers = ['Content-Type' => 'application/x-www-form-urlencoded']; $access_fields = "grant_type=client_credentials&client_id=...&client_secret=..."; $resp = curl_me($access_url, $access_headers, $access_fields); $access_token = json_decode($resp)->access_token; $rate_url = 'https://apis-sandbox.fedex.com/rate/v1/rates/quotes'; $rate_hdrs = [ 'Authorization' => 'Bearer '.$access_token, 'X-locale' => 'en_US', 'Content-Type' => 'application/json' ]; $rate_flds = '{ "accountNumber": { "value": "..." }, "requestedShipment": { "shipper": { "address": { "streetLines": [ "..." ], "city": "...", "stateOrProvinceCode": "...", "postalCode": "...", "countryCode": "US", "residential": false } }, "recipient": { "address": { "postalCode": "...", "countryCode": "US" } }, "shipDateStamp": "2022-12-06", "pickupType": "DROPOFF_AT_FEDEX_LOCATION", "requestedPackageLineItems": [{ "declaredValue": { "amount": 123, "currency": "USD" }, "weight": { "units": "LB", "value": 12 }, "dimensions": { "length": 12, "width": 12, "height": 12, "units": "IN" } }], "documentShipment": false, "packagingType": "YOUR_PACKAGING", "groupShipment": true }, "carrierCodes": [ "FDXE" ] }'; $field = build_post_fields($rate_flds); $resp = curl_me($rate_url, $rate_hdrs, $field); var_dump($resp);
curl_me函数
function curl_me($url, $headers, $postfields){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields); $response = curl_exec($ch); echo curl_error($ch); curl_close($ch); return $response; }
build_post_fields函数
function build_post_fields( $data,$existingKeys='',&$returnArray=[]){ if(($data instanceof CURLFile) or !(is_array($data) or is_object($data))){ $returnArray[$existingKeys]=$data; return $returnArray; } else{ foreach ($data as $key => $item) { build_post_fields($item,$existingKeys?$existingKeys."[$key]":$key,$returnArray); } return $returnArray; } }
问题原因分析
- 请求体格式错误:
build_post_fields函数用于将数组/对象转换为application/x-www-form-urlencoded格式的表单参数,但费率接口要求的是application/json格式的请求体。把JSON字符串传入该函数后,会被错误解析为键值对格式,导致接口无法识别请求内容。 - 未处理压缩响应:FedEx API默认返回gzip压缩的响应,当前curl配置未开启自动解压功能,获取到的是二进制压缩数据,表现为乱码。
解决步骤
1. 修正请求体传递方式
去掉build_post_fields的调用,直接将JSON字符串作为POST参数传入curl_me:
// 替换原$field = build_post_fields($rate_flds); $field = $rate_flds;
更规范的方式是用PHP数组构建数据后再json_encode,避免手动写JSON的转义问题:
$rate_flds = [ "accountNumber" => ["value" => "..."], "requestedShipment" => [ "shipper" => [ "address" => [ "streetLines" => ["..."], "city" => "...", "stateOrProvinceCode" => "...", "postalCode" => "...", "countryCode" => "US", "residential" => false ] ], "recipient" => ["address" => ["postalCode" => "...", "countryCode" => "US"]], "shipDateStamp" => "2022-12-06", "pickupType" => "DROPOFF_AT_FEDEX_LOCATION", "requestedPackageLineItems" => [[ "declaredValue" => ["amount" => 123, "currency" => "USD"], "weight" => ["units" => "LB", "value" => 12], "dimensions" => ["length" => 12, "width" => 12, "height" => 12, "units" => "IN"] ]], "documentShipment" => false, "packagingType" => "YOUR_PACKAGING", "groupShipment" => true ], "carrierCodes" => ["FDXE"] ]; $field = json_encode($rate_flds);
2. 开启curl自动解压功能
在curl_me函数中添加CURLOPT_ENCODING选项,让curl自动处理gzip/deflate压缩响应:
function curl_me($url, $headers, $postfields){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields); // 开启自动解压压缩响应 curl_setopt($ch, CURLOPT_ENCODING, ''); $response = curl_exec($ch); echo curl_error($ch); curl_close($ch); return $response; }
3. 验证请求头
确保rate_hdrs中的Content-Type确实为application/json,避免被其他代码意外修改。
测试修改后的代码
完成上述修改后,重新请求费率接口,即可得到正常的JSON格式响应,不再出现乱码。
内容的提问来源于stack exchange,提问作者hdap
相关产品推荐
相关产品推荐

