NuSOAP中addComplexType的$elements与$attrs使用规则是什么?
NuSOAP中$elements与$attrs参数详解
参考NuSOAP官方文档对两个参数的定义:
elements $elements = array ( name => array(name=>'',type=>'') ) attrs $attrs = array( array( 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" ) )
两个参数的核心定位
$elements:对应WSDL规范里的XML元素定义,用来声明当前复杂类型包含的所有子节点结构$attrs:对应WSDL规范里的XML属性定义,用来声明当前复杂类型节点上附带的元信息属性
你观察到的两个参数互换位置仍可正常运行,本质是NuSOAP的历史容错设计:这个库开发时间很早,没有做严格的参数位置校验,内部逻辑会自动识别传入数组的结构特征——只要匹配元素结构就自动归类到元素列表,匹配属性结构就自动归类到属性列表。这种写法不属于官方推荐的标准用法,老版本库的这种容错设计是为了兼容早期不规范的代码,实际开发还是要严格按照官方文档的参数顺序传参,避免后续库版本更新收紧校验逻辑后直接报错。
$elements的具体使用方法
这个参数用来定义结构体类型下的所有业务字段,最终会生成WSDL中的<xsd:element>节点,对应实际SOAP报文中、位于元素开始/结束标签之间的子节点。
- 传参格式:关联数组结构,键为元素名,值为该元素的类型配置,格式为
元素名 => ['type' => 元素对应的数据类型] - 适用场景:定义普通结构体的所有业务字段,比如预定义的
message结构体包含id、content两个字段时,传参示例:
$server->wsdl->addComplexType( 'message', 'complexType', 'struct', 'all', '', [ 'id' => ['name' => 'id', 'type' => 'xsd:int'], 'content' => ['name' => 'content', 'type' => 'xsd:string'] ], // 这里就是$elements,定义结构体的两个业务字段 [], // $attrs,普通结构体不需要额外属性 'tns:message' );
- 对应生成的SOAP报文结构:
<message> <id>1</id> <content>测试内容</content> </message>
$attrs的具体使用方法
这个参数用来定义当前复杂类型节点上的元属性,对应WSDL中的<xsd:attribute>节点,最终会生成在SOAP报文的元素开始标签内部,格式为属性名="属性值"的键值对,不属于业务字段。
- 传参格式:索引数组结构,每一项是一个属性的配置关联数组
- 适用场景:声明数组类型的元信息、附加的命名空间配置等非业务字段的元数据,最典型的场景就是定义数组类型时,声明数组的元素类型,也就是你代码中用到的配置。
'ref' =>参数的核心作用
这个写法基于XML Schema的通用引用规范,核心作用是省略重复的属性定义,直接复用全局已经声明过的类型。
- 正常定义一个SOAP数组属性,需要手动写全属性的完整元信息,包括命名空间、数据类型,写法类似:
[ 'name' => 'arrayType', 'type' => 'xsd:string', 'namespace' => 'http://schemas.xmlsoap.org/soap/encoding/' ]
- 用
ref的写法可以直接引用NuSOAP内部已经预先定义好的SOAP-ENC:arrayType属性(这个属性是SOAP编码标准里全局预先声明的),不需要重复写命名空间、类型等元信息,大幅简化代码,最终生成的属性结构和手写全量定义是完全一致的。
元素与属性的快速判断方法
实际开发不需要死记硬背规则,只需要对照SOAP报文的结构判断:
- 如果内容是被标签包裹、位于开始标签和结束标签之间的业务字段,放到
$elements中 - 如果内容是写在开始标签内部、与标签名同层级的键值对元信息,放到
$attrs中
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

