如何在PHP中的nuSoap上创建一个Web服务,返回一个可以从WCF调用的数组?

I have a webservice in PHP using nuSOAP. The webservice returns an array of objects. When using

$server->wsdl->addComplexType(
    "thingArray",         // type name
    "complexType",        // soap type
    'array',              // php type (struct/array)
    'sequence',           // composition (all/sequence/choice)
    '',                   // base restriction
    array(                // elements
       'item' => array(
           'name' => 'item',
           'type' => 'tns:thing',
           'minOccurs' => '0',
           'maxOccurs' => 'unbounded'
       )
   ),
   array(),              // attributes
   "tns:thing"           // array type
);

the WCF client fails when calling, complaining that it can't convert thing[] to thingArray.

First off - remember to turn on UTF8 so that WCF can understand the responses.

  // Configure UTF8 so that WCF will be happy
  $server->soap_defencoding='UTF-8';
  $server->decode_utf8=false;

To make WCF understand arrays we need to use the SOAP encoding for Arrays rather than the Sequence composition.

This will make nuSOAP emit an array that WCF can consume:

  $server->wsdl->addComplexType(
      'thingArray',          // type name
      'complexType',         // Soap type
      'array',               // PHP type (struct, array)
      '',                    // composition
      'SOAP-ENC:Array',      // base restriction
      array(),               // elements
      array(                 // attributes
        array(
          'ref'=>'SOAP-ENC:arrayType',
          'wsdl:arrayType'=>'tns:thing[]'
        )
      ),      // attribs
      "tns:thing"        // arrayType
  );

This type can now be used in the response, and the WCF client will happily consume the SOAP response that nuSOAP generates.

  // Register the method to expose
  $server->register('serviceMethod',           // method name
      array('param1' => 'tns:thingArray'),     // input parameters
      array('return' => 'tns:thingArray'),     // output parameters
      $ns,                                     // namespace
      $ns.'#serviceMethod',                    // soapaction
      'rpc',                                   // style
      'encoded',                               // use
      'Says hello'                             // documentation
  );

The WCF client ends up looking like this:

   var client = new Svc.servicePortTypeClient();
   thing[] things = new thing[3];
   thing[] result = client.serviceMethod(things);
   foreach( thing x in result )
   { ... do something with x ... }