2013-03-08 15 views
16

Próbuję wywołać metodę SOAP przy użyciu PHP.Tworzenie połączenia SOAP za pomocą PHP z treścią XML

Oto kod mam:

$data = array('Acquirer' => 
    array(
    'Id' => 'MyId', 
    'UserId' => 'MyUserId', 
    'Password' => 'MyPassword' 
)); 
$method = 'Echo'; 
$client = new SoapClient(NULL, 
      array('location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler', 
      'uri' => 'http://example.com/wsdl', 'trace' => 1)); 
$result = $client->$method($data); 

Oto wniosek tworzy:

<?xml version="1.0" encoding="UTF-8"?> 
    <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <SOAP-ENV:Body> 
     <ns1:Echo> 
     <param0 xsi:type="ns2:Map"> 
      <item> 
      <key xsi:type="xsd:string">Acquirer</key> 
      <value xsi:type="ns2:Map"> 
       <item> 
       <key xsi:type="xsd:string">Id</key> 
       <value xsi:type="xsd:string">mcp</value> 
       </item> 
       <item> 
       <key xsi:type="xsd:string">UserId</key> 
       <value xsi:type="xsd:string">tst001</value> 
       </item> 
       <item> 
       <key xsi:type="xsd:string">Password</key> 
       <value xsi:type="xsd:string">test</value> 
       </item> 
      </value> 
      </item> 
     </param0> 
     </ns1:Echo> 
    </SOAP-ENV:Body> 
    </SOAP-ENV:Envelope> 

A oto co Chcę wniosek wyglądać:

<?xml version="1.0" encoding="UTF-8"?> 
    <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <SOAP-ENV:Body> 
     <Echo> 
     <Acquirer> 
      <Id>MyId</Id> 
      <UserId>MyUserId</UserId> 
      <Password>MyPassword</Password> 
     </Acquirer> 
     </Echo> 
    </SOAP-ENV:Body> 
    </SOAP-ENV:Envelope> 
+1

Nie można tego rozwiązać bez kompletnych informacji WSDL. PHP SoapClient aktywnie analizuje i używa WSDL, aby umieścić argumenty funkcji we właściwych miejscach. Bez załadowanego WSDL prawie niemożliwe jest stworzenie czegoś, co działa. – Sven

+0

@Sven - to bardzo pomocne, chociaż nie rozwiązało to w pełni mojego problemu. Czy możesz to opublikować jako odpowiedź? Jeśli nikt inny nie odpowie, zaakceptuję to przynajmniej, ponieważ pomogło mi to nieco przejść dalej. – greggles

+0

Nie, dziękuję, masz lepszą odpowiedź, która może zasługiwać na nagrodę. – Sven

Odpowiedz

41

Istnieje kilka sposobów rozwiązania tego problemu. Najmniej hackiest i prawie co chcesz:

$client = new SoapClient(
    null, 
    array(
     'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler', 
     'uri' => 'http://example.com/wsdl', 
     'trace' => 1, 
     'use' => SOAP_LITERAL, 
    ) 
); 
$params = new \SoapVar("<Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer>", XSD_ANYXML); 
$result = $client->Echo($params); 

ten dostaje następujące XML:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl"> 
    <SOAP-ENV:Body> 
     <ns1:Echo> 
      <Acquirer> 
       <Id>MyId</Id> 
       <UserId>MyUserId</UserId> 
       <Password>MyPassword</Password> 
      </Acquirer> 
     </ns1:Echo> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

czyli prawie dokładnie to, co chcesz, z wyjątkiem nazw na nazwę metody. Nie wiem, czy to jest problem. Jeśli tak, możesz zhakować to jeszcze bardziej. można umieścić tag <Echo> w ciągu XML ręcznie i mają SoapClient nie ustawić metodę dodając 'style' => SOAP_DOCUMENT, do tablicy opcji, takich jak ten:

$client = new SoapClient(
    null, 
    array(
     'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler', 
     'uri' => 'http://example.com/wsdl', 
     'trace' => 1, 
     'use' => SOAP_LITERAL, 
     'style' => SOAP_DOCUMENT, 
    ) 
); 
$params = new \SoapVar("<Echo><Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer></Echo>", XSD_ANYXML); 
$result = $client->MethodNameIsIgnored($params); 

Skutkuje to następującą prośbę XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Body> 
     <Echo> 
      <Acquirer> 
       <Id>MyId</Id> 
       <UserId>MyUserId</UserId> 
       <Password>MyPassword</Password> 
      </Acquirer> 
     </Echo> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Wreszcie, jeśli chcesz grać z obiektami SoapVar i SoapParam, możesz znaleźć dobre odniesienie w tym komentarzu w podręczniku PHP: http://www.php.net/manual/en/soapvar.soapvar.php#104065. Jeśli sprawisz, że zadziała, daj mi znać, nie udało mi się.

8

Po pierwsze, trzeba określić chcesz użyć stylu dokumentu Literal:

$client = new SoapClient(NULL, array(
    'location' => 'https://example.com/path/to/service', 
    'uri' => 'http://example.com/wsdl', 
    'trace' => 1, 
    'use' => SOAP_LITERAL) 
); 

Następnie trzeba przekształcić swoje dane do SoapVar; Pisałem prostego przekształcenia funkcji:

function soapify(array $data) 
{ 
     foreach ($data as &$value) { 
       if (is_array($value)) { 
         $value = soapify($value); 
       } 
     } 

     return new SoapVar($data, SOAP_ENC_OBJECT); 
} 

Następnie zastosowaniu tej funkcji przekształcić na dane:

$data = soapify(array(
    'Acquirer' => array(
     'Id' => 'MyId', 
     'UserId' => 'MyUserId', 
     'Password' => 'MyPassword', 
    ), 
)); 

Wreszcie, wezwać serwis przechodzącą parametr danych:

$method = 'Echo'; 

$result = $client->$method(new SoapParam($data, 'Data')); 
+0

To jest właściwie pierwszy post na stackoverlow, który wspomniał o parametrze "Data" –

Powiązane problemy