Intereting Posts

Как передать массив в вызов 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> .

Я запускаю это как:

 $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('Ym-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('Ym-d', strtotime($order['checkin'])); $stay->end_date = date('Ym-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('Ym-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 сообщения 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> 

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

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

Предполагая, что при $soapClient экземпляра $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)) ); 

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

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

У меня также была эта проблема и нашел решение. Туда должен быть массив с восходящими клавишами, начиная с 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