Ik heb een zeer drukke tijd met webservices aan wie moet ik bellen met PHP en vandaag heb ik te maken gehad met SOAP headers. De waarheid is dat het een wereld is vrij donker en ik een ontmoeting met vele hindernissen. Ik zal u vertellen waar en hoe ik opgelost, maar laten we eerst eens kijken naar enkele theorie.

De web services zijn uitgegroeid tot de primaire wijze van informatie-uitwisseling tussen applicaties, ongeacht van de platforms, besturingssystemen en programmeertalen. SOAP is een van de protocollen waarop zijn gegevens uitgewisseld en is gebaseerd op XML, zodat de cliënt polls de server met een XML-formaat en ontvangt het antwoord in een andere XML. Om te begrijpen wat we bedoelen laten we eens kijken naar de structuur van een SOAP-verzoeken en antwoorden.

Bel (aanvraag):

  1. encoding = "UTF-8" ?> <? Xml version = "1.0" encoding = "UTF-8"?>
  2. xmlns:ns1= "com.xplota.ws" > Xmlns: SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/" xmlns: ns1 = <SOAP-ENV:Envelope "com.xplota.ws">
  3. <SOAP-ENV:Header>
  4. <ns1:entity>
  5. <code> 1 </ code>
  6. <desc> </ Desc>
  7. </ NS1: entiteit>
  8. <ns1:language>
  9. <code> 1 </ code>
  10. <desc> </ Desc>
  11. </ NS1: taal>
  12. <ns1:userId>
  13. <code> 1 </ code>
  14. <desc> </ Desc>
  15. </ NS1: gebruiker>
  16. </ SOAP-ENV: Header>
  17. <SOAP-ENV:Body>
  18. </ SOAP-ENV: Body>
  19. </ SOAP-ENV: Envelope>

Antwoord (respons):

  1. encoding = "utf-8" ?> <? Xml version = "1.0" encoding = "UTF-8"?>
  2. xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema" > <Soap: Envelop xmlns: zeep = "http://schemas.xmlsoap.org/soap/envelope/" xmlns: XSi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: xsd = " http://www.w3.org/2001/XMLSchema ">
  3. <soap:Header>
  4. > <status xmlns = "com.xplota.ws">
  5. <code> 0 </ code>
  6. <desc> Ok </ Desc>
  7. </ Status>
  8. </ Soap: Header>
  9. <soap:Body>
  10. </ Soap: Body>
  11. </ Soap: Envelope>

Zoals in eerdere aanbiedingen, zowel het verzoek en de reactie bestaat uit twee XML-knooppunten, kop en lichaam. De meest gebruikte is het lichaam (die ik leeg is omdat we niet geïnteresseerd zijn op dit moment) en die het antwoord bevatten zowel de parameters die worden verstuurd naar de webservice in het verzoek als terugkerende in het.

Het verzenden van zeep headers

In het onderhavige geval moet sturen bepaalde parameters in de header en lees vanaf daar mogelijke fout-codes, indien er sprake was geweest. De overbrenging, ondanks het feit dat een structuur in plaats van een eenvoudige parameter, was simpel, je een klasse te definiëren met de juiste parameters en wordt direct verzonden. De PHP SOAP engine is verantwoordelijk voor de vertaling. Beschouw een case study.

  1. / / Definieer de klasse headers
  2. wsHeader klasse
  3. (
  4. = 0 ; openbare $ code = 0;
  5. = ; Desc openbare $ = ";
  6. $code , $desc ) { publieke functie __construct ($ code, $ desc) (
  7. = $code ; Deze $ -> code = $ code;
  8. = $desc ; Deze $ -> Dalend = $ desc;
  9. )
  10. )
  11. / / Een voorbeeld van de SOAP client
  12. ( ) ; Par $ = array ();
  13. SoapClient ( "http://midominio.com/ws?wsdl" , $par ) ; $ Klant = nieuwe SoapClient ("http://midominio.com/ws?wsdl", $ par);
  14. / / Voeg de kop op verzoeken
  15. ( ) ; $ Headers = array ();
  16. = new SoapHeader ( "com.xplota.ws" , 'entity' , new wsHeader ( 1 , ) ) ; Headers $ [] = new SoapHeader (com.xplota.ws ',' entiteit ', nieuwe wsHeader (1 "));
  17. = new SoapHeader ( "com.xplota.ws" , 'language' , new wsHeader ( 1 , ) ) ; Headers $ [] = new SoapHeader (com.xplota.ws ',' taal ', de nieuwe wsHeader (1 "));
  18. = new SoapHeader ( "com.xplota.ws" , 'userId' , new wsHeader ( 1 , ) ) ; Headers $ [] = new SoapHeader (com.xplota.ws ',' userid ', nieuwe wsHeader (1 "));
  19. $headers ) ; $ Client -> __setSoapHeaders ($ headers);
  20. / / Start de aanroep van de methode van de was
  21. -> TuMetodo ( $parametros ) ; $ Result = $ client -> TuMetodo ($ params);

Zoals u kunt zien is vrij eenvoudig te begrijpen. Door het toevoegen van een header moet aangeven de naamruimte het behoort tot de SOAP engine weet hoe het te behandelen, is een naam, en het object die het bevat.

Met dit hebben we opgelost de perszijde van onze hoofden en hebben een SOAP-verzoek als we in de eerste XML.

Het ontvangen van SOAP headers

Nu dat de methode in onze webservice zegt met een aantal andere headers die we weten hoe we tot de notering interpreteren van de XML-respons als de tweede. Dan hebben wij een zeer groot probleem. Er is geen manier om headers krijgt deze de motor van de PHP SOAP retourneert alleen het lichaam, nooit headers.

Volgens de PHP handmatige methode __soapCall SOAP client headers definiëren een array, die deze zullen terugkeren, maar ik was niet in staat om de syntax van draaien het inroepen van een webservice met deze methode, terwijl een beroep op hen rechtstreeks op de klant (hoe documentatie stelt dat kan worden gedaan) Ik werkte het perfect. Dat is de theorie zegt dat de eerste methode kan ik headers krijgen, maar ik werkte terwijl ik werkte, maar de tweede geeft hij de headers en er is geen manier om ze terug te vorderen.

Na een lange ruzie met SOAP-functies en onderzoek, maar nog niet aangekomen bij iedere conclusie, het is alsof het was gebeurd voor iedereen, heb ik niets vinden nuttig. Ik had een enige oplossing, maak mijn eigen klasse uit de SOAP XML oorspronkelijke reactie op het proces met de hand om de benodigde gegevens te verkrijgen. Gezegd en gedaan. Laat de oplossing.

Eerst heb ik mijn eigen soort van zeep en ik controleren of ik kan doen wat ik wil.

  1. SoapClient { XSoapClient klasse breidt SoapClient (
  2. $wsdl , $options ) { publieke functie __construct ($ WSDL, $ options) (
  3. , $options ) ; ouder:: __construct ($ WSDL, $ options);
  4. )
  5. $request , $location , $action , $version ) { publieke functie __doRequest ($ verzoek, $ locatie, $ actie, $ versie) (
  6. $request , $location , $action , $version ) ; $ Response = ouder:: __doRequest ($ verzoek, $ locatie, $ actie, $ versie);
  7. ; return $ response;
  8. )
  9. )
  10. XSoapClient ( "http://midominio.com/ws?wsdl" , $par ) ; $ Klant = nieuwe XSoapClient (http://midominio.com/ws?wsdl ", $ par);

Ik denk dat ik geluk als ik dit proberen nieuwe SOAP client werkt perfect, maar ook als ik de inhoud van $ response zie ik dat bevat de volledige XML webservice antwoord. Hoe zie je het enige dat verandert is dat het gebeurd instantiëren de naam van de nieuwe klasse. Goed begin, als ik mijn kaarten goed te spelen kan ik de headers __doRequest krijgen in de methode :) .

Laten we daar dit XML om te krijgen wat we willen. Dankzij de functies DOM en XPath in PHP is zeer eenvoudig. Dit is het eindresultaat van mijn cliënt herstel SOAP headers:

  1. SoapClient klasse SoapClient breidt XSoapClient
  2. (
  3. = array ( ) ; particuliere $ responseHeaders = array ();
  4. $wsdl , $options ) { publieke functie __construct ($ WSDL, $ options) (
  5. , $options ) ; ouder:: __construct ($ WSDL, $ options);
  6. )
  7. $request , $location , $action , $version ) { publieke functie __doRequest ($ verzoek, $ locatie, $ actie, $ versie) (
  8. $request , $location , $action , $version ) ; $ Response = ouder:: __doRequest ($ verzoek, $ locatie, $ actie, $ versie);
  9. DOMDocument; Dom $ = new DOMDocument;
  10. ( $response , LIBXML_NOWARNING ) ; $ Dom -> loadXML ($ response, LIBXML_NOWARNING)
  11. DOMXPath ( $dom ) ; $ Path = nieuwe DOMXPath ($ dom);
  12. ( 'soap' , 'http://schemas.xmlsoap.org/soap/envelope/' ) ; $ Path -> registerNamespace ('zeep', 'http://schemas.xmlsoap.org/soap/envelope/');
  13. -> query ( '//soap:Header/*' ) ; Xml = $ $ path -> query ("/ / soap: Header / * ');
  14. = $this -> headers2array ( $xml ) ; Deze $ -> responseHeaders = $ this -> headers2array ($ xml);
  15. ; return $ response;
  16. )
  17. getResponseHeaders publieke functie () (
  18. -> responseHeaders ; return $ this -> responseHeaders;
  19. )
  20. $response ) { headers2array private functie ($ response) (
  21. ( ) ; $ Headers = array ();
  22. $response as $node ) { foreach ($ response als $ node) (
  23. $node -> hasChildNodes ( ) ) { if ($ node -> hasChildNodes ()) (
  24. $node -> nodeName ] = $this -> headers2array ( $node -> childNodes ) ; Headers $ [$ node -> NODename] = $ this -> headers2array ($ node -> childNodes);
  25. { Else ()
  26. $node -> nodeName ] = $node -> nodeValue ; Headers $ [$ node -> NODename] = $ node -> nodeValue;
  27. )
  28. )
  29. ; return $ headers;
  30. )
  31. )
  32. = new XSoapClient ( "http://midominio.com/ws?wsdl" , $par ) ; lang = <pre "php"> $ client = nieuwe XSoapClient (http://midominio.com/ws?wsdl ", $ par);
  33. -> TuMetodo ( $parametros ) ; $ Result = $ client -> TuMetodo ($ params);
  34. -> getResponseHeaders ( ) ; Soapheaders $ = $ client -> getResponseHeaders ();

Probleem opgelost en heel elegant. Als iemand weet hoe je de headers te krijgen zonder dat het samenvoegen van alle deze ellende u mij vertellen aub.

Als je hun nut hebben bewezen dit artikel ... Share!