title: How to pass an array into a PHP SoapClient call
body: <p>Using PHP and SoapClient.</p>
  
  <p>I need to pass the following XML into a soap request - i.e. multiple <code>&lt;stay&gt;</code>'s within <code>&lt;stays&gt;</code>.</p>
  
  <pre><code>&lt;reservation&gt;
      &lt;stays&gt;
          &lt;stay&gt;
              &lt;start_date&gt;2011-01-01&lt;/start_date&gt;
              &lt;end_date&gt;2011-01-15&lt;/end_date&gt;
          &lt;/stay&gt;
          &lt;stay&gt;
              &lt;start_date&gt;2011-01-16&lt;/start_date&gt;
              &lt;end_date&gt;2011-01-30&lt;/end_date&gt;
          &lt;/stay&gt;
      &lt;/stays&gt;
  &lt;/reservation&gt;
  </code></pre>
  
  <p>The problem is that I'm passing the data in as an array:</p>
  
  <pre><code>$xml = array('reservation' =&gt; array(
      'stays' =&gt; array(
          array(
              'start_date' =&gt; '2011-01-01',
              'end_date'   =&gt; 2011-01-15
          ),
          array(
              'start_date' =&gt; '2011-01-16',
              'end_date'   =&gt; 2011-01-30
          )
      )
  );
  </code></pre>
  
  <p>The above doesn't work, as <code>&lt;stay&gt;</code> is not defined.  So the alternative is:</p>
  
  <pre><code>$xml = array('reservation' =&gt; array(
      'stays' =&gt; array(
          'stay' =&gt; array(
              'start_date' =&gt; '2011-01-01',
              'end_date'   =&gt; 2011-01-15
          ),
          'stay' =&gt; array(
              'start_date' =&gt; '2011-01-01',
              'end_date'   =&gt; 2011-01-15
          )
      )
  );
  </code></pre>
  
  <p>But that results in duplicate keys, so only one of the <code>&lt;stay&gt;</code>'s is sent.</p>
  
  <p>I'm running this as:</p>
  
  <pre><code>$soapClient-&gt;saveReservation($xml);
  </code></pre>
  
  <p>Any ideas on how I can structure the array so that the above XML is generated?</p>
  
  <hr>
  
  <p>Some further information.  The above examples were super-simplified, so here's a real use example of what I'm doing, with benjy's suggestion implemented.</p>
  
  <pre><code>$options = $this-&gt;api-&gt;getDefaultOptions();
  $options['baseProductCode'] = '123'.$basket-&gt;accommodation['feed_primary_identifier'];
  #                             ^^^^^ just to ensure it fails and doesn't process
  $reservation = new stdClass();
  
  $reservation-&gt;external_id = $order-&gt;pb_ref;
  $reservation-&gt;etab_id = $basket-&gt;accommodation['feed_primary_identifier'];
  $reservation-&gt;reservation_type = 'gin';
  $reservation-&gt;firstname = $order-&gt;forename;
  $reservation-&gt;lastname  = $order-&gt;surname;
  $reservation-&gt;birthdate = date('Y-m-d', strtotime('- 21 YEAR'));
  $reservation-&gt;stays = array();
  $details = $basket-&gt;getDetailedBasketContents();
  foreach ($details['room_types'] as $roomTypeId =&gt; $roomType) {
    foreach($roomType['instances'] as $instance) {
      $stay = new stdClass();
      $stay-&gt;nb_rooms = 1;
      $stay-&gt;room_type_code = $roomTypeId;
      $stay-&gt;start_date = date('Y-m-d', strtotime($order['checkin']));
      $stay-&gt;end_date   = date('Y-m-d', strtotime($order['checkout']));
      $stay-&gt;occupants  = array();
      foreach($instance['occupancy']['occupants'] as $key =&gt; $occupantData) {
        if ($occupantData['forename'] and $occupantData['surname']) {
          $occupant = new stdClass();
          $occupant-&gt;firstname = $occupantData['forename'];
          $occupant-&gt;lastname  = $occupantData['surname'];
          $occupant-&gt;pos = 100;
          $occupant-&gt;birthdate = date('Y-m-d', strtotime('- 21 YEAR'));
          $stay-&gt;occupants[] = $occupant;
        }
      }
      $reservation-&gt;stays[] = $stay;
    }
  }
  
  $options['reservation'] = new stdClass();
  $options['reservation']-&gt;reservation = $reservation;
  
  
  //echo XmlUtil::formatXmlString($this-&gt;api-&gt;);
  
  try {
    $this-&gt;parsePlaceOrderResponse($this-&gt;api-&gt;__soapCall('saveDistribReservation2', $options));
  } catch (Exception $e) {
    echo $e-&gt;getMessage();
    echo XmlUtil::formatXmlString($this-&gt;api-&gt;__getLastRequest());
    echo XmlUtil::formatXmlString($this-&gt;api-&gt;__getLastResponse());
  }
  exit;
  </code></pre>
  
  <p>This fails, with the message <code>object hasn't 'stay' property</code> which is due to the same issue, that the <code>&lt;stays&gt;</code> tag should contain 1 or more <code>&lt;stay&gt;</code> tags.  If I set <code>$reservation-&gt;stays['stay'] = $stay;</code> then it is accepted, but that again only allows me to have a single <code>&lt;stay&gt;</code> within <code>&lt;stays&gt;</code></p>
  
  <p>Additionally, the SOAP request looks like this:</p>
  
  <pre><code>&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hom="homingwns" xmlns:v1="..."&gt;
     &lt;soapenv:Header/&gt;
     &lt;soapenv:Body&gt;
        &lt;hom:saveDistribReservation2&gt;
           &lt;base_id&gt;?&lt;/base_id&gt;
           &lt;username&gt;?&lt;/username&gt;
           &lt;password&gt;?&lt;/password&gt;
           &lt;partnerCode&gt;?&lt;/partnerCode&gt;
           &lt;baseProductCode&gt;?&lt;/baseProductCode&gt;
           &lt;reservation&gt;
              &lt;v1:reservation&gt;
                 &lt;v1:external_id&gt;?&lt;/v1:external_id&gt;
                 &lt;v1:etab_id&gt;?&lt;/v1:etab_id&gt;
                 &lt;v1:reservation_type&gt;?&lt;/v1:reservation_type&gt;
                 &lt;!--Optional:--&gt;
                 &lt;v1:option_date&gt;?&lt;/v1:option_date&gt;
                 &lt;!--Optional:--&gt;
                 &lt;v1:gender&gt;?&lt;/v1:gender&gt;
                 &lt;!--Optional:--&gt;
                 &lt;v1:firstname&gt;?&lt;/v1:firstname&gt;
                 &lt;v1:lastname&gt;?&lt;/v1:lastname&gt;
                 &lt;!--Optional:--&gt;
                 &lt;v1:birthdate&gt;?&lt;/v1:birthdate&gt;
                 &lt;!--Optional:--&gt;
                 &lt;v1:stays&gt;
                    &lt;v1:stay&gt;
                       &lt;v1:nb_rooms&gt;?&lt;/v1:nb_rooms&gt;
                       &lt;v1:room_type_code&gt;?&lt;/v1:room_type_code&gt;
                       &lt;v1:start_date&gt;?&lt;/v1:start_date&gt;
                       &lt;v1:end_date&gt;?&lt;/v1:end_date&gt;
                       &lt;!--Optional:--&gt;
                       &lt;v1:occupants&gt;
                          &lt;!--Optional:--&gt;
                          &lt;v1:occupant&gt;
                             &lt;!--Optional:--&gt;
                             &lt;v1:gender&gt;?&lt;/v1:gender&gt;
                             &lt;!--Optional:--&gt;
                             &lt;v1:firstname&gt;?&lt;/v1:firstname&gt;
                             &lt;v1:lastname&gt;?&lt;/v1:lastname&gt;
                             &lt;!--Optional:--&gt;
                             &lt;v1:birthdate&gt;?&lt;/v1:birthdate&gt;
                             &lt;v1:pos&gt;?&lt;/v1:pos&gt;
                          &lt;/v1:occupant&gt;
                       &lt;/v1:occupants&gt;
                    &lt;/v1:stay&gt;
                 &lt;/v1:stays&gt;
              &lt;/v1:reservation&gt;
           &lt;/reservation&gt;
        &lt;/hom:saveDistribReservation2&gt;
     &lt;/soapenv:Body&gt;
  &lt;/soapenv:Envelope&gt;
  </code></pre>