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

PHP多维数组转XML序列化失败 SOAP接口返回序列化错误求助

问题原因

  1. 自定义XML转换函数逻辑存在缺陷:原函数处理索引数组时,未按要求将每个子项包裹在<item>标签中,同时变量$child的作用域逻辑错误,导致items节点下无法生成符合要求的子节点,服务端无法识别内容直接丢弃,返回空的items标签。
  2. 数组字段与WSDL定义的Schema不匹配:
    • 根级name字段为完整姓名,Schema要求拆分为name和surname两个独立字段
    • 根级where_from字段与Schema要求的from字段名不符
    • 地址下的vat_number字段与Schema要求的post_code字段名不符
    • items子数组的键为cook、clean,但Schema明确要求每个子项必须包含name、material两个字段,字段不匹配导致服务端序列化失败。

修复方案

步骤1:调整数组字段匹配Schema要求

先把原始数组的字段转换为WSDL要求的格式:

// 你的原始数组
$original = [
    "name" => "John Doe",
    "date" => "2021-11-30 00:00:00.000",
    "job" => "developer",
    "where_from" => "france",
    "address" => [
        "country" => "france",
        "city" => "paris",
        "vat_number" => "123456"
    ],
    "items" => [
        ["cook" => "spoon", "clean" => "vacuum"]
    ]
];

// 转换为符合Schema的数组
$matched = [
    'name' => explode(' ', $original['name'])[0],
    'surname' => explode(' ', $original['name'])[1],
    'job' => $original['job'],
    'from' => $original['where_from'],
    'address' => [
        'country' => $original['address']['country'],
        'city' => $original['address']['city'],
        'post_code' => $original['address']['vat_number']
    ],
    'items' => [
        ['name' => 'spoon', 'material' => 'metal'],
        ['name' => 'vacuum', 'material' => 'plastic']
    ]
];

步骤2:修复XML转换函数

修复原函数的索引数组处理逻辑和变量作用域问题:

function convertToXml($data, $name='root', &$doc=null, &$node=null){
    if ($doc === null){
        $doc = new DOMDocument('1.0','UTF-8');
        $doc->formatOutput = TRUE;
        $node = $doc;
    }

    if (is_array($data)){
        $parent = $doc->createElement($name);
        $node->appendChild($parent);
        foreach($data as $key => $value){
            if (is_numeric($key)){
                // 索引数组子项统一用item标签包裹
                convertToXml($value, 'item', $doc, $parent);
            }else{
                convertToXml($value, $key, $doc, $parent);
            }
        }
    }else{
        $child = $doc->createElement($name);
        $child->appendChild($doc->createTextNode($data));
        $node->appendChild($child);
    }

    if ($doc === $node) {
        return $doc->saveXML();
    }
}

可选优化方案

不需要手动拼接XML,直接使用PHP内置的SoapClient类处理,它会自动根据WSDL的Schema完成数组序列化,避免手动转换的格式错误:

try {
    $client = new SoapClient('你的服务WSDL地址', [
        'encoding' => 'UTF-8',
        'exceptions' => true
    ]);
    $response = $client->Person($matched);
    var_dump($response);
} catch (SoapFault $e) {
    var_dump($e->getMessage());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:45:01