Отправка необработанного XML через запрос PHP SoapClient

Я пытаюсь просто отправить RAW xml на веб-сервис через PHP и SoapClient. Проблема в том, что когда я кодирую свой XML, он меняет порядок элементов в XML, который преобразуется в ассоциативный массив.

// Initialize the Soap Client:
$this->_transactionServicesClient = new SoapClient($soapWSDLUrl);

Как или что было бы лучшим способом отправить следующий XML в виде строки моему SoapClient?

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.micros.com/pos/les/TransactionServices">
    <SOAP-ENV:Body>
        <ns1:PostTransaction>
            <ns1:REQ>
                <ns1:RequestHeader>
                    <ns1:InterfaceVersion>3.0.7</ns1:InterfaceVersion>
                    <ns1:ClientName>TRANS_SERVICES</ns1:ClientName>
                </ns1:RequestHeader>    
                <ns1:CheckDetailEntries>
                    <ns1:MenuItem>
                        <ns1:ReferenceEntry>Pizza4</ns1:ReferenceEntry>
                        <ns1:Count>1</ns1:Count>
                        <ns1:Price>10.00</ns1:Price>
                        <ns1:ItemNumber>112001</ns1:ItemNumber>
                        <ns1:PriceLevel>1</ns1:PriceLevel>
                        <ns1:Seat xsi:nil="true"/>
                    </ns1:MenuItem>
                </ns1:CheckDetailEntries>
                <ns1:CheckHeaderRequest>
                    <ns1:CheckId>03:21:05.050505</ns1:CheckId>
                    <ns1:GuestCount>1</ns1:GuestCount>
                    <ns1:GuestInformation>
                    <ns1:ID>001</ns1:ID>
                    <ns1:FirstName>xxx</ns1:FirstName>
                    <ns1:LastName>xxx</ns1:LastName>
                    <ns1:Address1>xxx Rd</ns1:Address1>
                    <ns1:Address2>xx</ns1:Address2>
                    <ns1:Address3>xx</ns1:Address3>
                    <ns1:PhoneNum>xx</ns1:PhoneNum>
                    <ns1:UserText1>None</ns1:UserText1>
                    <ns1:UserText2>None</ns1:UserText2>
                    <ns1:UserText3>None</ns1:UserText3>
                    <ns1:GUID></ns1:GUID></ns1:GuestInformation>
                </ns1:CheckHeaderRequest>
                <ns1:OrderTypeNumber>1</ns1:OrderTypeNumber>
            </ns1:REQ>
        </ns1:PostTransaction>
    </SOAP-ENV:Body>        
</SOAP-ENV:Envelope>

Обновление/решение: вот код, который я использовал для расширения клиента SOAP и отправки необработанного конверта Soap: My ответ ниже


person Fostah    schedule 07.03.2012    source источник
comment
Я запутался: вы отправляете этот XML в службу SOAP, и он не анализируется, или у вас есть XML, который вы хотите отправить внутри сообщения SOAP?   -  person enygma    schedule 08.03.2012
comment
У меня есть XML, который я хочу отправить в мыльном сообщении. Когда я отправляю данные, закодированные в ассоциативном массиве, узлы теряют свой первоначальный порядок, что нарушает запрос. Пример: внутри CheckDetailEntries вы можете иметь теги MenuItem или Condiment. Но чтобы связать приправы с элементами меню, они должны быть в определенном порядке, который теряется при кодировании XML. Поэтому мне просто нужно отправить строку XML в метод PostTransaction для обработки.   -  person Fostah    schedule 08.03.2012
comment
Есть ли другой способ связать их? Полагаться на порядок входящего XML кажется мне немного хрупким...   -  person enygma    schedule 08.03.2012
comment
К сожалению, именно так работает этот Micros TransactionServices. Все приправы должны следовать за элементом меню, с которым они связаны.   -  person Fostah    schedule 08.03.2012


Ответы (2)


Обновление/решение: вот код, который я использовал для расширения клиента SOAP и отправки необработанного конверта Soap.

Вот как я расширил SoapClient:

<?php
class MySoapClient extends SoapClient {

    function __construct($wsdl, $options) {
        parent::__construct($wsdl, $options);
        $this->server = new SoapServer($wsdl, $options);
    }
    public function __doRequest($request, $location, $action, $version) 
    { 
        $result = parent::__doRequest($request, $location, $action, $version); 
        return $result; 
    } 
    function __myDoRequest($array,$op) { 
        $request = $array;
        $location = 'http://xxxxx:xxxx/TransactionServices/TransactionServices6.asmx';
        $action = 'http://www.micros.com/pos/les/TransactionServices/'.$op;
        $version = '1';
        $result =$this->__doRequest($request, $location, $action, $version);
        return $result;
    } 
}

// To invoke my new custom method with my Soap Envelope already prepared.
$soapClient = new MySoapClient("http://xxxx:xxxx/TransactionServices/TransactionServices6.asmx?WSDL", array("trace" => 1)); 
$PostTransaction = $soapClient->__myDoRequest($orderRequest,$op); 
?>

Также опубликовано на pastie.org: http://pastie.org/3687935, прежде чем я превратил это в ответ.

person Fostah    schedule 11.06.2013
comment
Вы только что передали свою XML-строку как $orderRequest? - person fibono; 11.11.2015

В целях тестирования вы можете создать подкласс SoapClient и переопределить метод __doRequest — он получает сгенерированный XML, и вы можете его предварительно обработать.

Но лучше найти, что не так с кодировкой XML. Вы можете использовать экземпляры SoapVar и SoapParam, чтобы указать точный способ представления данного объекта. Они спасли мне жизнь, когда нужно было указать пространства имен.

person Maxim Krizhanovsky    schedule 07.03.2012
comment
Что происходит, так это то, что когда мой XML кодируется в ассоциативный массив, он теряет порядок элементов внутри CheckDetailEntries. В моем XML у меня есть MenuItem, Condiment, MenuItem, Condiment. Но когда XML преобразуется, он группирует [MenuItems][0] и [MenuItems][1], которые затем при декодировании создают порядок MenuItem, MenuItem, Condiment, Condiment, что приводит к тому, что обе приправы связаны с последним MenuItem. Я рассмотрю SoapVar и SoapParam. Спасибо! - person Fostah; 08.03.2012
comment
Можно ли отправить _soapCall с именем функции, и вместо отправки аргументов в виде массива я могу вместо этого отправить строку XML? Я не могу понять, как это сделать. Спасибо! - person Fostah; 08.03.2012
comment
@Fostah, поскольку вы приняли ответ, очевидно, это помогло вам отладить / исправить программу, но не могли бы вы опубликовать, что именно послужило причиной неправильного XML? - person Maxim Krizhanovsky; 29.03.2012
comment
В итоге я расширил свой SoapClient и создал собственный метод _doRequest, позволяющий мне напрямую отправлять сформированный Soap Envelope. Вот рабочий результат pastie.org/3687935. - person Fostah; 29.03.2012