php - PHP SOAP 类转换如何工作以及如何获得一致的列表结果?

标签 php soap soap-client

所以我目前正在尝试使用 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>

可能会返回:

<someParamList>
  <someParam>foo</someParam>
  <someParam>bar</someParam>
</someParamList>

或者:

<someParamList>
  <someParam>foo</someParam>
</someParamList>

我已将 someParamList 映射到 SomeParamListClass 使用 classmap 属性将 someParam 转换为 SomeParamClass。一般来说,这工作得很好,但是取决于结果,我并不总是得到SomeParamClass数组。如果列表中只有 1 个结果,PHP 将直接设置对象而不是包含单个对象的数组。

我尝试在 __construct __set 或普通 setter 中转换数据,但都没有被调用。

所以: 为什么 SoapClient 的行为如此奇怪,为什么它从不调用构造函数或 setter ? 如何获得一致的列表?

最佳答案

与各种反序列化例程一样,SoapClient 不会将值传递给您可以拦截的构造函数或 setter ,它只是使用“神奇”设置的值在内部创建对象。

您可以做的是使用 typemap 选项而不是 classmap,它允许您分配用于转换类型的回调,而不是类名。

但是,使用 $options 参数可以更轻松地绕过“智能”列表格式:

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 - PHP SOAP 类转换如何工作以及如何获得一致的列表结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52588989/

相关文章:

php - 使用php下载最新的wordpress zip文件?

c# - 如何在不添加 Web 引用的情况下调用 SOAP Web 服务

java - 如何使用 CXF 在服务器端启用压缩?

c# - IRS-A2A BulkRequestTransmitter消息格式不正确和/或无法解释

java - CXF 客户端安全

php - 当用户来自书签时获取以前的 URL?

php - If 语句调用自定义样式表

php - 分析可变长度

php - 在 SOAP WSDL 调用 PHP 上获取 500 内部服务器错误

delphi - 按名称动态调用 SOAP 方法?