You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    }
}

问题原因分析

  1. 请求体格式错误:build_post_fields函数用于将数组/对象转换为application/x-www-form-urlencoded格式的表单参数,但费率接口要求的是application/json格式的请求体。把JSON字符串传入该函数后,会被错误解析为键值对格式,导致接口无法识别请求内容。
  2. 未处理压缩响应: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:35:20