2010-09-23 14 views
12

Korzystanie z PHP i SoapClient.Jak przekazać tablicę do wywołania funkcji SoapClient PHP

Potrzebuję przekazać następujące XML do żądania mydła - tj. Wiele <stay> w ciągu <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> 

Problemem jest to, że jestem przekazywania danych w postaci tablicy:

$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 
     ) 
    ) 
); 

Powyższe nie działa, jak <stay> nie jest zdefiniowana. Więc alternatywą jest:

$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 
     ) 
    ) 
); 

Ale to skutkuje duplikatów kluczy, więc tylko jeden z wysłaniem <stay> „s.

biegnę to jako:

$soapClient->saveReservation($xml); 

pomysłów, w jaki sposób mogę uporządkować tablicę tak, że powyższy XML jest generowany?


Kilka dalszych informacji. Powyższe przykłady zostały bardzo uproszczone, więc oto przykład użycia tego, co robię, z zaimplementowaną sugestią benjya.

$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; 

nie ten, z komunikatem object hasn't 'stay' property co wynika z tej samej kwestii, że znacznik <stays> powinien zawierać 1 lub więcej <stay> tagi. Jeżeli ustawić $reservation->stays['stay'] = $stay; to jest akceptowane, ale to znowu tylko pozwala mi mieć pojedynczy <stay> ciągu <stays>

Dodatkowo, żądanie SOAP wygląda następująco:

<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

Dlaczego po prostu nie serializacji tablicy „” pobytów i przypisać zawartość do elementu xml . Po stronie odbierającej można łatwo go odserializować. – stillstanding

+0

Nie mam kontroli nad mydlanym punktem końcowym. Musi to być XML zgodnie z wsdl. Ale jest to dość standardowa struktura XML, więc musi istnieć sposób na jej reprezentację. – Colin

+0

Zobacz także http://stackoverflow.com/questions/577795/passing-array-to-soap-function-in-php –

Odpowiedz

18

"Pobyt" należy zdefiniować tylko jeden raz. To powinna być właściwa odpowiedź:

$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

Dzięki, ale to pytanie ma 2 1/2 lat i nie jestem w pracy, nie mówiąc już o tym samym projekcie, więc nie jestem w stanie przetestować/zweryfikować. Dziękuję za przyczynienie się. – Colin

+0

Proszę pana, jesteś geniuszem! Właśnie tego szukałem ... działa jak urok. Dziękuję bardzo! – incutonez

+1

Widząc, jak odpowiedziałeś trzy lata po pytaniu, wydaje się właściwe, że przyjmuję to przez kolejne trzy lata na: p - Wygląda na to, że incutonez zweryfikował rozwiązanie. – Colin

3

Zakładając, że podczas wystąpienia $soapClient, ty nie tak w trybie WSDL, następujące powinny działać:

$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

Dzięki. Dam ci to - pomocna jest baza danych na punkcie końcowym, więc nie mogę jej przetestować, ale zrobię to najszybciej. – Colin

+0

Nie widzę jednak, jak to się stanie, ponieważ wiele znaczników jest w tym miejscu, ale zakładam, że wiesz coś, czego nie robię - zrobi to, gdy tylko będę mógł. – Colin

+1

Re: nie widzisz, jak to zadziała - zaufaj mi, nikt inny nie. Klient SOAP PHP jest do dupy. – benjy

0

Spróbuj tego:

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

Też miałem ten problem i znalazłem rozwiązanie. Pobyty musi być tablicą z kluczami wznoszących zaczynając od 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); 

znalazłem moją odpowiedź na tej stronie: https://bugs.php.net/bug.php?id=45284

Powiązane problemy