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

SOAP API调用请求体始终为空问题求助(附PHP代码)

解决Colissimo SOAP API调用请求体为空的问题

我之前也遇到过类似的SOAP API参数映射问题,你的核心问题在于传递给generateLabel方法的参数没有正确匹配WSDL定义的命名参数,导致SOAP客户端无法识别并序列化你的请求数据。

问题分析

你当前的调用代码是:

$api_result = $soap_client->generateLabel(array($api_struct));

这里用了索引数组传递参数,但SOAP客户端需要明确知道每个参数对应WSDL里的哪个字段名(比如Colissimo的generateLabel接口需要一个名为generateLabelRequest的参数)。索引数组无法被客户端正确映射,所以生成的XML里只留下了空的<ns1:generateLabel/>标签。

另外,你代码里有很多冗余的new stdClass()操作(比如$api_params->outputFormat = new stdClass();之后又直接赋值$output_format),这些完全可以删掉,简化代码逻辑。

解决方案

步骤1:确认WSDL的参数定义

先运行以下代码,查看SOAP客户端解析出的函数签名,明确参数名:

print_r($soap_client->__getFunctions());

你会看到类似这样的输出:

Array
(
    [0] => generateLabelResponse generateLabel(generateLabelRequest $generateLabelRequest)
)

这说明generateLabel方法需要一个名为generateLabelRequest的参数。

步骤2:修改调用方式(两种可选)

方法一:使用命名数组+SoapVar(推荐,确保类型严格匹配)

用关联数组指定参数名,同时通过SoapVar明确指定WSDL中的类型命名空间:

try {
    $api_result = $soap_client->generateLabel([
        'generateLabelRequest' => new SoapVar(
            $api_params, 
            SOAP_ENC_OBJECT, 
            'generateLabelRequest', 
            'http://sls.ws.coliposte.fr'
        )
    ]);
} catch(Exception $e) {
    // 保留你的错误调试代码
}
方法二:直接传递对象(如果客户端支持自动映射)

如果SOAP客户端能自动识别对象结构,也可以直接传递命名参数:

try {
    $api_result = $soap_client->generateLabel([
        'generateLabelRequest' => $api_params
    ]);
} catch(Exception $e) {
    // 保留你的错误调试代码
}

优化后的完整代码示例

我帮你清理了冗余的代码,同时加入了正确的调用逻辑:

$api_params = new stdClass();
$api_params->contractNumber = "********";
$api_params->password = "********";

// 构建outputFormat
$output_format = new stdClass();
$output_format->x = 0;
$output_format->y = 0;
$output_format->outputPrintingType = "PDF_10x15_300dpi";
$api_params->outputFormat = $output_format; // 去掉冗余的new stdClass()

// 构建letter
$api_params->letter = new stdClass();

// 构建service
$service = new stdClass();
$service->productCode = "DOM";
$service->orderNumber = $order_id;
$service->commercialName = TEXT_SENDER_NAME;
$api_params->letter->service = $service; // 去掉冗余的new stdClass()

// 构建parcel
$parcel = new stdClass();
$parcel->weight = $weight;
$api_params->letter->parcel = $parcel; // 去掉冗余的new stdClass()

// 构建sender
$sender = $this->get_sender();
$api_params->letter->sender = new stdClass();
$api_params->letter->sender->senderParcelRef = randomise_order_num($order_id);
$api_params->letter->sender->address = $sender;

// 构建addressee
$addressee = $this->get_addressee($order_id);
$api_params->letter->addressee = $addressee; // 去掉冗余的new stdClass()

// 初始化SOAP客户端
$wsdl = "https://ws.colissimo.fr/sls-ws/SlsServiceWS?wsdl";
$soap_client = new SoapClient($wsdl, array('trace' => true, 'exception' => true));

// 调试用:查看函数签名
// print_r($soap_client->__getFunctions());

try {
    // 正确调用API
    $api_result = $soap_client->generateLabel([
        'generateLabelRequest' => new SoapVar(
            $api_params, 
            SOAP_ENC_OBJECT, 
            'generateLabelRequest', 
            'http://sls.ws.coliposte.fr'
        )
    ]);
    
    echo "========= RESPONSE =========" . PHP_EOL;
    print_r($api_result);
} catch(Exception $e) {
    echo "====== REQUEST HEADERS =====" . PHP_EOL;
    var_dump($soap_client->__getLastRequestHeaders());
    echo "========= REQUEST ==========" . PHP_EOL;
    echo htmlentities($soap_client->__getLastRequest()) . PHP_EOL;
    echo "========= ERROR =========" . PHP_EOL;
    echo $e->getMessage() . PHP_EOL;
}

关键要点

  • SOAP API调用必须使用命名参数,索引数组无法被客户端正确映射到WSDL定义。
  • 用__getFunctions()可以快速确认WSDL中的参数名和类型,避免猜谜。
  • 冗余的new stdClass()操作不仅没用,还会增加代码的混乱度,建议清理。

内容的提问来源于stack exchange,提问作者akabaka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:57:38