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

在Laravel中使用Laminas SOAP生成带复杂子类型的WSDL

问题:Laravel中使用Laminas SOAP生成多层级WSDL

我正在尝试在Laravel中使用Laminas SOAP生成包含多层级结构的WSDL,查阅相关文档及工具后仍未理清配置方式。现有代码及当前WSDL结构如下:

控制器代码

public function soap()
{
    $server = new Server(
        route('soap-wsdl'),
        [
            'actor' => route('soap-server'),
        ]
    );

    $this->populateServer($server);
    $server->setReturnResponse(true);

    $response = response($server->handle());
    $response->header('Content-Type', 'text/xml');

    return $response;
}

public function wsdl(Request $request)
{
    $wsdl = new AutoDiscover();

    $this->populateServer($wsdl);
    $wsdl->setUri(route('soap-server'))
        ->setServiceName('InaportWSDL');

    return response()->make($wsdl->toXml())
        ->header('Content-Type', 'application/xml');
}

private function populateServer($server)
{
    // Expose a class and its methods:
    $server->setClass(ResponseServices::class);
}

ResponseServices类代码

class ResponseServices {
/**
 * @param string $user
 * @param string $password
 * @param array $detail
 */
public function entryRpkro($user, $password, $detail)
{
}

}

当前WSDL请求结构

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
    <entryRpkro xmlns="http://localhost:8000/soap">
        <user>[string]</user>
        <password>[string]</password>
        <detail>[Array]</detail>
    </entryRpkro>
</Body>
</Envelope>

期望的WSDL请求结构

希望detail字段包含name和age子字段,结构如下:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
    <entryRpkro xmlns="http://localhost:8000/soap">
        <user>[string]</user>
        <password>[string]</password>
        <detail>
          <name>[string]</name>
          <age>[int]</age>
        </detail>
    </entryRpkro>
</Body>
</Envelope>

解决方案

1. 创建Detail实体类

定义一个代表detail结构的类,通过PHPDoc注释声明字段类型,让Laminas SOAP自动识别该复杂类型:

class Detail {
    /**
     * @var string
     */
    public $name;

    /**
     * @var int
     */
    public $age;
}

2. 修改ResponseServices类的参数注释

将原@param array $detail替换为@param Detail $detail,告知Laminas SOAP该参数为自定义复杂类型:

class ResponseServices {
/**
 * @param string $user
 * @param string $password
 * @param Detail $detail
 */
public function entryRpkro($user, $password, $detail)
{
}

}

3. 确保AutoDiscover识别自定义类型

若自动发现不生效,可在生成WSDL的方法中手动注册Detail类:

public function wsdl(Request $request)
{
    $wsdl = new AutoDiscover();
    // 手动注册复杂类型
    $wsdl->addComplexType(Detail::class);
    
    $this->populateServer($wsdl);
    $wsdl->setUri(route('soap-server'))
        ->setServiceName('InaportWSDL');

    return response()->make($wsdl->toXml())
        ->header('Content-Type', 'application/xml');
}

验证效果

重新生成WSDL后,detail字段将包含name和age子节点,符合期望的多层级结构。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:58:10