PHP SOAP class 转换如何工作以及如何获得一致的列表结果?
How does PHP SOAP class transformation work and how do I get consistent list results?
所以我目前正在尝试使用 PHP SoapClient 实现外部 API 调用 - 我发现它以一种非常奇怪的方式工作。
假设我有以下 WSDL 定义:
<xs:element name="someParamList">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="someParam" type="someParam"/>
</xs:sequence>
</xs:complexType>
</xs:element>
可能return:
<someParamList>
<someParam>foo</someParam>
<someParam>bar</someParam>
</someParamList>
或:
<someParamList>
<someParam>foo</someParam>
</someParamList>
我已将 someParamList 映射到 SomeParamListClass
和 someParam 到 SomeParamClass
使用 classmap
属性。这在一般情况下工作正常,但是 取决于结果我并不总是得到 SomeParamClass
的 array
。如果列表中只有 1 个结果,PHP 将直接设置对象而不是包含单个对象的数组。
我尝试转换 __construct
__set
或正常 setter 中的数据,但都没有被调用。
所以:
为什么 SoapClient 行为如此奇怪,为什么它从不调用构造函数或 setters?
我如何获得一致的列表?
与各种反序列化例程一样,SoapClient 不会将值传递给构造函数或您可以拦截的 setter,它只是在内部创建对象并设置 "magically" 值。
您可以改为使用 typemap
选项而不是 classmap
,它允许您为转换类型分配回调,而不是 class 名称。
但是,使用 $options
参数可以更轻松地绕过 "smart" 列表格式:
features
option is a bitmask of ... SOAP_SINGLE_ELEMENT_ARRAYS ...
这在任何地方都没有真正描述,但它强制解码 XML 的 每个 元素成为一个数组,而不是试图猜测哪些是单一的,哪些是这是多个。这可能意味着您将不得不写 $response[0]['foo'][0]['bar'][0]
很多,但至少它是可以预测的。
所以:
$client = new SoapClient(
$wsdl,
[
// other options which you're already passing here...
'features' => SOAP_SINGLE_ELEMENT_ARRAYS
]
);
所以我目前正在尝试使用 PHP SoapClient 实现外部 API 调用 - 我发现它以一种非常奇怪的方式工作。
假设我有以下 WSDL 定义:
<xs:element name="someParamList">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="someParam" type="someParam"/>
</xs:sequence>
</xs:complexType>
</xs:element>
可能return:
<someParamList>
<someParam>foo</someParam>
<someParam>bar</someParam>
</someParamList>
或:
<someParamList>
<someParam>foo</someParam>
</someParamList>
我已将 someParamList 映射到 SomeParamListClass
和 someParam 到 SomeParamClass
使用 classmap
属性。这在一般情况下工作正常,但是 取决于结果我并不总是得到 SomeParamClass
的 array
。如果列表中只有 1 个结果,PHP 将直接设置对象而不是包含单个对象的数组。
我尝试转换 __construct
__set
或正常 setter 中的数据,但都没有被调用。
所以: 为什么 SoapClient 行为如此奇怪,为什么它从不调用构造函数或 setters? 我如何获得一致的列表?
与各种反序列化例程一样,SoapClient 不会将值传递给构造函数或您可以拦截的 setter,它只是在内部创建对象并设置 "magically" 值。
您可以改为使用 typemap
选项而不是 classmap
,它允许您为转换类型分配回调,而不是 class 名称。
但是,使用 $options
参数可以更轻松地绕过 "smart" 列表格式:
features
option is a bitmask of ... SOAP_SINGLE_ELEMENT_ARRAYS ...
这在任何地方都没有真正描述,但它强制解码 XML 的 每个 元素成为一个数组,而不是试图猜测哪些是单一的,哪些是这是多个。这可能意味着您将不得不写 $response[0]['foo'][0]['bar'][0]
很多,但至少它是可以预测的。
所以:
$client = new SoapClient(
$wsdl,
[
// other options which you're already passing here...
'features' => SOAP_SINGLE_ELEMENT_ARRAYS
]
);