2010-09-23 10 views
12

En utilisant PHP et SoapClient.Comment passer un tableau dans un appel PHP SoapClient

J'ai besoin de passer le code XML suivant dans une demande de savon - c'est-à-dire plusieurs <stay> dans <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> 

Le problème est que je passe les données comme un tableau:

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

Le ne fonctionne pas, comme <stay> n'est pas défini. Ainsi, l'alternative est:

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

Mais qui se traduit par un double des clés, de sorte que l'un des est envoyé du <stay>.

Je suis en cours d'exécution comme cela:

$soapClient->saveReservation($xml); 

Toutes les idées sur la façon dont je peux structurer le tableau afin que le XML ci-dessus est généré?


Plus d'informations. Les exemples ci-dessus ont été très simplifiés, alors voici un exemple concret de ce que je fais, avec la suggestion de benjy implémentée.

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

Cela échoue, le message object hasn't 'stay' property qui est dû à la même question, que l'étiquette <stays> doit contenir 1 ou plusieurs <stay> tags. Si je mets $reservation->stays['stay'] = $stay; alors il est accepté, mais encore une fois ne me permet d'avoir un seul <stay> au sein <stays>

En outre, la requête SOAP ressemble à ceci:

<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

Pourquoi ne pas simplement sérialiser le tableau « séjours » et affecter le contenu à l'élément xml . Du côté réception, vous pouvez le désérialiser facilement. – stillstanding

+0

Je n'ai aucun contrôle sur le point final du savon. Il doit être XML selon le wsdl. Mais il s'agit d'une structure XML assez standard, il doit donc y avoir un moyen de la représenter. – Colin

+0

Voir aussi http://stackoverflow.com/questions/577795/passing-array-to-soap-function-in-php –

Répondre

18

'stay' doit être défini une seule fois. Cela devrait être la bonne réponse:

$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

Merci, mais cette question est de 2 ans et demi, et je ne suis pas au travail, encore moins le même projet, donc je ne suis pas en mesure de tester/vérifier. Merci d'avoir contribué. – Colin

+0

Monsieur, vous êtes un génie! C'est exactement ce que je cherchais ... fonctionne comme un charme. Merci beaucoup! – incutonez

+1

Voyant que vous avez répondu trois ans après la question, il semble approprié que je l'accepte encore trois ans sur: p - On dirait qu'incutonez vérifié la solution. – Colin

3

En supposant que lorsque vous instancié $soapClient, vous a fait en mode WSDL, ce qui suit devrait fonctionner:

$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

Merci. Je vais essayer - utilement la base de données sur le point final est en panne pour le moment, je ne peux pas le tester, mais je vais le faire dès que possible. – Colin

+0

Je ne vois pas comment cela va obtenir les multiples étiquettes là, mais je suppose que vous savez quelque chose que je ne sais pas - je vais essayer une fois que je peux. – Colin

+1

Re: vous ne voyez pas comment cela va fonctionner - faites-moi confiance, personne d'autre ne le fait. Le client SOAP de PHP est nul. – benjy

0

Essayez ceci:

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

J'ai également eu ce problème et trouvé la solution. Stays doit être un tableau avec les touches ascendantes commençant par 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); 

J'ai trouvé ma réponse sur cette page: https://bugs.php.net/bug.php?id=45284