2010-09-23 3 views
12

Использование PHP и SoapClient.Как передать массив в вызов PHP SoapClient

Мне нужно передать следующий XML-запрос в мыло, то есть несколько <stay> в пределах <stays>.

<reservation> 
    <stays> 
     <stay> 
      <start_date>2011-01-01</start_date> 
      <end_date>2011-01-15</end_date> 
     </stay> 
     <stay> 
      <start_date>2011-01-16</start_date> 
      <end_date>2011-01-30</end_date> 
     </stay> 
    </stays> 
</reservation> 

Проблема заключается в том, что я передаю данные в виде массива:

$xml = array('reservation' => array(
    'stays' => array(
     array(
      'start_date' => '2011-01-01', 
      'end_date' => 2011-01-15 
     ), 
     array(
      'start_date' => '2011-01-16', 
      'end_date' => 2011-01-30 
     ) 
    ) 
); 

выше не работает, так как <stay> не определен. Так что альтернатива:

$xml = array('reservation' => array(
    'stays' => array(
     'stay' => array(
      'start_date' => '2011-01-01', 
      'end_date' => 2011-01-15 
     ), 
     'stay' => array(
      'start_date' => '2011-01-01', 
      'end_date' => 2011-01-15 
     ) 
    ) 
); 

Но это приводит к дублированию ключей, так что только один из <stay> «s посылается.

Я бегу это как:

$soapClient->saveReservation($xml); 

Любые идеи о том, как я могу структурировать массив так, что генерируется выше XML?


Дополнительная информация. Вышеприведенные примеры были упрощены, так что вот реальный пример того, что я делаю, с предложением benjy.

$options = $this->api->getDefaultOptions(); 
$options['baseProductCode'] = '123'.$basket->accommodation['feed_primary_identifier']; 
#        ^^^^^ just to ensure it fails and doesn't process 
$reservation = new stdClass(); 

$reservation->external_id = $order->pb_ref; 
$reservation->etab_id = $basket->accommodation['feed_primary_identifier']; 
$reservation->reservation_type = 'gin'; 
$reservation->firstname = $order->forename; 
$reservation->lastname = $order->surname; 
$reservation->birthdate = date('Y-m-d', strtotime('- 21 YEAR')); 
$reservation->stays = array(); 
$details = $basket->getDetailedBasketContents(); 
foreach ($details['room_types'] as $roomTypeId => $roomType) { 
    foreach($roomType['instances'] as $instance) { 
    $stay = new stdClass(); 
    $stay->nb_rooms = 1; 
    $stay->room_type_code = $roomTypeId; 
    $stay->start_date = date('Y-m-d', strtotime($order['checkin'])); 
    $stay->end_date = date('Y-m-d', strtotime($order['checkout'])); 
    $stay->occupants = array(); 
    foreach($instance['occupancy']['occupants'] as $key => $occupantData) { 
     if ($occupantData['forename'] and $occupantData['surname']) { 
     $occupant = new stdClass(); 
     $occupant->firstname = $occupantData['forename']; 
     $occupant->lastname = $occupantData['surname']; 
     $occupant->pos = 100; 
     $occupant->birthdate = date('Y-m-d', strtotime('- 21 YEAR')); 
     $stay->occupants[] = $occupant; 
     } 
    } 
    $reservation->stays[] = $stay; 
    } 
} 

$options['reservation'] = new stdClass(); 
$options['reservation']->reservation = $reservation; 


//echo XmlUtil::formatXmlString($this->api->); 

try { 
    $this->parsePlaceOrderResponse($this->api->__soapCall('saveDistribReservation2', $options)); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
    echo XmlUtil::formatXmlString($this->api->__getLastRequest()); 
    echo XmlUtil::formatXmlString($this->api->__getLastResponse()); 
} 
exit; 

Это не удается, с сообщением object hasn't 'stay' property что связано с той же проблемой, что <stays> тег должен содержать 1 или более <stay> тегов. Если я устанавливаю $reservation->stays['stay'] = $stay; тогда принято, но это опять же только позволяет мне иметь один <stay> в <stays>

Кроме того, запрос SOAP выглядит следующим образом:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hom="homingwns" xmlns:v1="..."> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <hom:saveDistribReservation2> 
     <base_id>?</base_id> 
     <username>?</username> 
     <password>?</password> 
     <partnerCode>?</partnerCode> 
     <baseProductCode>?</baseProductCode> 
     <reservation> 
      <v1:reservation> 
       <v1:external_id>?</v1:external_id> 
       <v1:etab_id>?</v1:etab_id> 
       <v1:reservation_type>?</v1:reservation_type> 
       <!--Optional:--> 
       <v1:option_date>?</v1:option_date> 
       <!--Optional:--> 
       <v1:gender>?</v1:gender> 
       <!--Optional:--> 
       <v1:firstname>?</v1:firstname> 
       <v1:lastname>?</v1:lastname> 
       <!--Optional:--> 
       <v1:birthdate>?</v1:birthdate> 
       <!--Optional:--> 
       <v1:stays> 
        <v1:stay> 
        <v1:nb_rooms>?</v1:nb_rooms> 
        <v1:room_type_code>?</v1:room_type_code> 
        <v1:start_date>?</v1:start_date> 
        <v1:end_date>?</v1:end_date> 
        <!--Optional:--> 
        <v1:occupants> 
         <!--Optional:--> 
         <v1:occupant> 
          <!--Optional:--> 
          <v1:gender>?</v1:gender> 
          <!--Optional:--> 
          <v1:firstname>?</v1:firstname> 
          <v1:lastname>?</v1:lastname> 
          <!--Optional:--> 
          <v1:birthdate>?</v1:birthdate> 
          <v1:pos>?</v1:pos> 
         </v1:occupant> 
        </v1:occupants> 
        </v1:stay> 
       </v1:stays> 
      </v1:reservation> 
     </reservation> 
     </hom:saveDistribReservation2> 
    </soapenv:Body> 
</soapenv:Envelope> 
+0

Почему не просто сериализовать массив «STAYS» и присвоить содержимое XML-элемент , На принимающей стороне вы можете легко ее неэтериализовать. – stillstanding

+0

У меня нет контроля над конечной точкой мыла. Он должен быть XML в соответствии с wsdl. Но это довольно стандартная XML-структура, поэтому должен быть способ ее представления. – Colin

+0

См. Также http://stackoverflow.com/questions/577795/passing-array-to-soap-function-in-php –

ответ

18

«stay» должен быть определен только один раз. Это должен быть правильный ответ:

$xml = array('reservation' => array(
'stays' => array(
    'stay' => array(
        array(
          'start_date' => '2011-01-01', 
          'end_date' => 2011-01-15 
        ), 
        array(
          'start_date' => '2011-01-01', 
          'end_date' => 2011-01-15 
        ) 
      ) 
    ) 
)); 
+0

Спасибо, но этот вопрос составляет 2 1/2 года, и я не нахожусь на работе, не говоря уже о том же проекте, поэтому я не могу проверить/проверить. Спасибо за вклад. – Colin

+0

Сэр, вы гений! Это именно то, что я искал ... работает как шарм. Спасибо огромное! – incutonez

+1

Увидев, как вы ответили через три года после вопроса, мне кажется уместным, что я принимаю его еще на три года: p - Похоже, что интунезон проверил решение. – Colin

3

Если предположить, что, когда вы инстанцирован $soapClient, вы сделал это в режиме WSDL, следующее должно работать:

$stay1 = new stdClass(); 
$stay1->start_date = "2011-01-01"; 
$stay1->end_date = "2011-01-15"; 
$stay2 = new stdClass(); 
$stay2->start_date = "2011-01-01"; 
$stay2->end_date = "2011-01-15"; 
$stays = array(); 
$stays[0] = $stay1; 
$stays[1] = $stay2; 
$soapClient->saveReservation(
    array("reservation" => array("stays" => $stays)) 
); 
+0

Спасибо. Я дам, что пойдет - на данный момент база данных на конечной точке не работает, поэтому я не могу ее протестировать, но я буду делать как можно скорее. – Colin

+0

Я не вижу, как это получится, если есть несколько тегов , но я предполагаю, что вы знаете что-то, чего я не знаю, - когда-нибудь мне это удастся. – Colin

+1

Re: Вы не видите, как это будет работать - поверьте мне, никто другой не сделает. PHP SOAP-клиент отстой. – benjy

0

Попробуйте это:

$xml = array(
    'stays' => array(
    'stay' => array(
     array(/* start end */), 
     array(/* start end */), 
     array(/* start end */) 
    ) 
) 
); 
0

У меня также была эта проблема и я нашел решение. Пакеты должны быть массив с ключами, восходящими, начиная с 0.

$client = new SoapClient('http://myservice.com?wsdl'); 
$stays[] = array('startDate'=>'01-01-2013', 'endDate'=>'02-02-2013'); 
$stays[] = array('startDate'=>'02-02-2013', 'endDate'=>'03-03-2013'); 
$params = array(
    'reservation' => array('stays'=>$stays) 
); 
$client->saveReservation($params); 

Я нашел ответ на этой странице: https://bugs.php.net/bug.php?id=45284

Смежные вопросы