【问题标题】:Returning a PHP Array from a PHP SoapServer从 PHP SoapServer 返回 PHP 数组
【发布时间】:2009-07-23 23:06:56
【问题描述】:

在“创建服务端”方面,我对 Soap 比较陌生,因此请提前对我正在使用的任何术语表示歉意。

是否可以从使用 PHP 的 SoapServer 类设置的远程过程 Soap 服务返回 PHP 数组?

我有一个 WSDL(通过盲目地按照教程构建),部分看起来像这样

<message name='genericString'>
    <part name='Result' type='xsd:string'/>
</message>

<message name='genericObject'>
    <part name='Result' type='xsd:object'/>
</message>

<portType name='FtaPortType'>       
    <operation name='query'>
        <input message='tns:genericString'/>
        <output message='tns:genericObject'/>
    </operation>        
</portType>

我调用的 PHP 方法名为查询,看起来像这样

public function query($arg){
    $object = new stdClass();
    $object->testing = $arg;
    return $object;     
}

这让我可以打电话

$client = new SoapClient("http://example.com/my.wsdl");
$result = $client->query('This is a test');

结果转储看起来像

object(stdClass)[2]
    public 'result' => string 'This is a test' (length=18)

我想从我的查询方法中返回一个原生 PHP 数组/集合。如果我更改我的查询方法以返回一个数组

public function query($arg) {
    $object = array('test','again');
    return $object;
}

它在客户端被序列化成一个对象。

object(stdClass)[2]
    public 'item' => 
        array
            0 => string 'test' (length=4)
            1 => string 'again' (length=5)

这是有道理的,因为我在我的 WSDL 中将 xsd:object 指定为 Result 类型。如果可能的话,我想返回一个未包含在 Object 中的原生 PHP 数组。我的直觉说有一个特定的 xsd:type 可以让我完成这个,但我不知道。我也会满足于将对象序列化为ArrayObject

不要阻止我学习 WSDL 的技术细节。我正在尝试掌握 fo 的基本概念

【问题讨论】:

    标签: php soap wsdl soapserver


    【解决方案1】:

    小技巧 - 编码为 JSON 对象,解码回递归关联数组:

    $data = json_decode(json_encode($data), true);
    

    【讨论】:

    • 已经知道了,但是你提醒我的地方对了!谢谢:-)
    【解决方案2】:

    我使用this WSDL generator创建描述文件。

    返回字符串数组是我的 Web 服务所做的事情,这是 WSDL 的一部分:

    <wsdl:types>
    <xsd:schema targetNamespace="http://schema.example.com">
      <xsd:complexType name="stringArray">
        <xsd:complexContent>
          <xsd:restriction base="SOAP-ENC:Array">
            <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:string[]" />
          </xsd:restriction>
        </xsd:complexContent>
      </xsd:complexType>
    </xsd:schema>
    
    </wsdl:types>
    <message name="notifyRequest">
      <part name="parameters" type="xsd:string" />
    </message>
    <message name="notifyResponse">
      <part name="notifyReturn" type="tns:stringArray" />
    </message>
    

    然后定义API函数notify

    <wsdl:operation name="notify">
      <wsdl:input message="tns:notifyRequest" />
      <wsdl:output message="tns:notifyResponse" />
    </wsdl:operation>
    

    【讨论】:

      【解决方案3】:

      艾伦,当您的客户收到响应时,为什么不将您的对象转换为数组?

      例如

      (array) $object;
      

      这会将您的 stdClass 对象转换为数组,对此没有可测量的开销,并且在 PHP 中是 O(1)。

      您可能还想尝试将类型从 xsd:object 更改为 soap-enc:Array。

      【讨论】:

      • 两个原因。因为这会给我一个数组,其中包含一个名为“item”的键,其中包含我的数组,更重要的是,我想创建一个服务,最终用户可以使用并从中获取数组,而无需强制转换它。
      • soap-enc:Array 不适合您的需求?
      • 请记住,这不会递归转换。因此,如果您在响应的更深层次中有 stdClass 对象,它们将不会被转换。在这种情况下,我能想到的唯一方法就是 lubosdz 的回答。
      猜你喜欢
      • 1970-01-01
      • 2013-05-15
      • 2017-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多