在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
相关产品推荐
相关产品推荐

