2010-09-23 36 views
12

Sử dụng PHP và SoapClient.Cách chuyển một mảng vào cuộc gọi PHP SoapClient

Tôi cần chuyển XML sau vào yêu cầu xà phòng - nghĩa là nhiều <stay> trong phạm vi <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> 

Vấn đề là tôi đang đi qua các dữ liệu trong như một mảng:

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

ở trên không hoạt động, như <stay> không được định nghĩa. Vì vậy, sự lựa chọn là:

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

Nhưng điều đó dẫn đến trùng lặp phím, vì vậy chỉ một trong những 's <stay> được gửi đi.

Tôi đang chạy này như:

$soapClient->saveReservation($xml); 

Bất kỳ ý tưởng về làm thế nào tôi có thể cấu trúc mảng sao cho XML ở trên được tạo ra?


Một số thông tin khác. Các ví dụ trên đã được đơn giản hóa siêu, vì vậy đây là một ví dụ sử dụng thực tế về những gì tôi đang làm, với đề xuất của benjy được thực hiện.

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

này thất bại, với thông điệp object hasn't 'stay' property đó là do cùng một vấn đề, đó là thẻ <stays> nên chứa 1 hoặc nhiều <stay> thẻ. Nếu tôi đặt $reservation->stays['stay'] = $stay; sau đó nó được chấp nhận, nhưng điều đó lại chỉ cho phép tôi để có một đơn <stay> trong <stays>

Bên cạnh đó, yêu cầu SOAP trông như thế này:

<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

Tại sao không chỉ serialize mảng 'ở lại' và gán nội dung vào các yếu tố xml . Ở phía bên nhận, bạn có thể unserialize nó một cách dễ dàng. – stillstanding

+0

Tôi không có quyền kiểm soát điểm cuối xà phòng. Nó phải là XML theo wsdl. Nhưng đây là một cấu trúc XML khá chuẩn nên phải có cách để thể hiện nó. – Colin

+0

Xem thêm http://stackoverflow.com/questions/577795/passing-array-to-soap-function-in-php –

Trả lời

18

'lưu trú' phải được xác định chỉ một lần. Đây phải là câu trả lời đúng:

$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

Cảm ơn, nhưng câu hỏi này là 2 1/2 năm tuổi, và tôi không ở công việc, hãy để một mình cùng một dự án, vì vậy tôi không thể kiểm tra/xác minh. Cảm ơn bạn đã đóng góp. – Colin

+0

Thưa bạn, bạn là một thiên tài! Đây chính xác là những gì tôi đang tìm kiếm ... hoạt động như một sự quyến rũ. Cảm ơn bạn rất nhiều! – incutonez

+1

Thấy như bạn đã trả lời ba năm sau câu hỏi, có vẻ như thích hợp mà tôi chấp nhận nó thêm ba năm nữa: p - Hình như incutonez đã xác minh giải pháp. – Colin

3

Giả sử rằng khi bạn khởi tạo $soapClient, bạn đã làm như vậy trong chế độ WSDL, sau đây nên làm việc:

$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

Cảm ơn. Tôi sẽ cung cấp cho rằng một đi - helpfully cơ sở dữ liệu trên điểm cuối là xuống vào lúc này vì vậy tôi không thể kiểm tra nó, nhưng tôi sẽ làm càng sớm càng tốt. – Colin

+0

Tôi không thấy làm thế nào điều này sẽ nhận được nhiều thẻ trong đó mặc dù, nhưng tôi giả sử bạn biết một cái gì đó tôi không - sẽ cung cấp cho nó một khi tôi có thể. – Colin

+1

Re: bạn không thấy làm thế nào điều này sẽ làm việc - tôi tin tưởng, không ai khác làm. Ứng dụng SOAP của PHP rất tệ. – benjy

0

Hãy thử điều này:

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

Tôi cũng gặp vấn đề này và tìm ra giải pháp. Trú cần phải được một mảng với các phím tăng dần bắt đầu với 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); 

Tôi tìm thấy câu trả lời của tôi trên trang này: https://bugs.php.net/bug.php?id=45284

Các vấn đề liên quan