title: PHP SoapParam/SoapVar for complex type gives "object hasn't 'xxx' property" - repeating element
body: <p>This question relates to the use of SoapParam and SoapVar in a PHP SOAP client to handle repeating elements, where requests cannot be framed as associative arrays. More particularly, it addresses a difficulty in using SoapParam/SoapVar for complex elements.</p>
  
  <p>I have working code that I am trying to modify to allow a repeated element in the SOAP request.</p>
  
  <p>The working code is as follows and correctly returns details of a single consignmentID.</p>
  
  <pre><code>$oClient = new SoapClient($wsdlFilespec, $arguments);
  $parameters = array(
     'header' =&gt; array(
        'source' =&gt; $_POST['source'],
        'accountNo' =&gt; $_POST['accountNo'],
        'userAccessKey' =&gt; $connection['userAccessKey']
        ),
     'consignmentId' =&gt; $_POST['consignmentId']
       );
  $request = array('parameters' =&gt; $parameters);
  $result = $oClient-&gt;__soapCall($operation, $request);
  </code></pre>
  
  <p>I now need to be able to pass in multiple consignmentIds and obviously an associative array won't work for that. So I have been trying to use SoapParam and SoapVar; not finding a lot of documentation or examples for these by the way.</p>
  
  <p>I have tried the following:</p>
  
  <pre><code>$header = array(
     new SoapParam((string)$_POST['source'], 'source'), 
     new SoapParam((int)$_POST['accountNo'], 'accountNo'),
     new SoapParam((string)$connection['userAccessKey'], 'userAccessKey')
    );
  
  $parameters = array(
     new SoapParam($header, 'header'),
     new SoapParam((string)'PDH44109', 'consignmentId'),
     new SoapParam((string)'PDH44110', 'consignmentId')
       );
  $request = array('parameters' =&gt; $parameters);
  </code></pre>
  
  <p>This gives: SOAP-ERROR: Encoding: object hasn't 'header' property.</p>
  
  <p>I have also tried using SoapVar in hopes of forcing the complex type of 'header', as follows:</p>
  
  <pre><code>$header = array(
    new SoapParam((string)$_POST['source'], 'source'), 
    new SoapParam((int)$_POST['accountNo'], 'accountNo'),
    new SoapParam((string)$connection['userAccessKey'], 'userAccessKey')
    );
  $headerVar = new SoapVar($header, SOAP_ENC_OBJECT, 'TransactionHeaderType',     
  "http://myexpress/Common/actions/externals/Consignment/v1");
  
  $parameters = array(
             new SoapParam($headerVar, 'header'),
     new SoapParam((string)'PDH44109', 'consignmentId'),
     new SoapParam((string)'PDH44110', 'consignmentId')
       );
  $request = array('parameters' =&gt; $parameters);
  </code></pre>
  
  <p>This also gives: SOAP-ERROR: Encoding: object hasn't 'header' property.</p>
  
  <p>I have also tried variations on the last line of code such as:</p>
  
  <pre><code>$request = array('parameters' =&gt; $parameters);
  $request = array($parameters);
  $request = $parameters;
  </code></pre>
  
  <p>As an experiment I temporarily assigned a string to $header and then was able to peek at the XML generated by __soapCall prior to calling __doRequest and found that it contained the following:</p>
  
  <pre><code>&lt;SOAPENV:Body&gt;&lt;ns1:getConsignmentDetailRequest/&gt;
  &lt;consignmentId&gt;PDH44109&lt;/consignmentId&gt;&lt;consignmentId&gt;PDH44110&lt;/consignmentId&gt;
  &lt;/SOAP-ENV:Body&gt;
  </code></pre>
  
  <p>You can see that the multiple consignments have been correctly included -- that part seems to be solved -- but 'header' (a complex type) is omitted completely. </p>
  
  <p>Would so much appreciate any help whatever! I am a real beginner and have spent more than a day on this. Am quite uncertain with SoapVar, for example, what the appropriate parameters are.</p>
  
  <p>Perhaps there is an issue with the typing of 'header'? Have provided some wsdl extracts below for reference.</p>
  
  <pre><code>------
  
  &lt;wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://my.com.au/ESB/Services/Concrete/External/Services/v1" 
  
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns0="http://myexpress/Common/actions/externals/Consignment/v1" 
  
  xmlns:ns1="http://myexpress/Common/externals/Faultv1" xmlns:ns2="http://myexpress/Common/actions/externals/FreightCalculation/v1" 
  
  xmlns:ns3="http://myexpress/Common/Primitives/v1" xmlns:ns4="http://myexpress/Common/FreightProcessing/v1" 
  
  xmlns:ns5="http://myexpress/Common/Account/v1" xmlns:ns6="http://myexpress/Common/Imaging/v1" name="Untitled" 
  
  targetNamespace="http://my.com.au/ESB/Services/Concrete/External/Services/v1"&gt;
  
  ------
  
          &lt;xsd:schema xmlns="http://myexpress/Common/Primitives/v1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  
  xmlns:acc="http://myexpress/Common/Account/v1" targetNamespace="http://myexpress/Common/Primitives/v1" elementFormDefault="qualified" 
  
  attributeFormDefault="unqualified"&gt;
              &lt;xsd:import namespace="http://myexpress/Common/Account/v1"/&gt;
     .
     .
     .
     .
  
             &lt;xsd:complexType name="TransactionHeaderType"&gt;
                  &lt;xsd:sequence&gt;
                      &lt;xsd:element name="source" type="xsd:string"/&gt;
                      &lt;xsd:element name="accountNo" type="xsd:integer"/&gt;
                      &lt;xsd:element name="userAccessKey" type="xsd:string"/&gt;
                      &lt;xsd:element name="userId" type="ns3:userIdType" minOccurs="0"/&gt;
                      &lt;xsd:element name="transactionId" type="ns3:transactionIdType" minOccurs="0"/&gt;
                      &lt;xsd:element name="transactionDatetime" type="xsd:dateTime" minOccurs="0"/&gt;
                  &lt;/xsd:sequence&gt;
              &lt;/xsd:complexType&gt;
  
  ------
  
              &lt;xsd:simpleType name="consignmentIdType"&gt;
                  &lt;xsd:restriction base="xsd:string"&gt;
                      &lt;xsd:maxLength value="30"/&gt;
                  &lt;/xsd:restriction&gt;
              &lt;/xsd:simpleType&gt;
  
  ------
  
              &lt;xsd:element name="getConsignmentDetailRequest"&gt;
                  &lt;xsd:complexType&gt;
                      &lt;xsd:sequence&gt;
                          &lt;xsd:element name="header" type="prim:TransactionHeaderType"/&gt;
                          &lt;xsd:element name="consignmentId" type="ns0:consignmentIdType" maxOccurs="unbounded"/&gt;
                      &lt;/xsd:sequence&gt;
                  &lt;/xsd:complexType&gt;
              &lt;/xsd:element&gt;
  
  ------
  </code></pre>