Čo je SOAP? Úvod do schémy XML

Ahojte všetci!
Stalo sa, že som nedávno začal vyvíjať webové služby. Ale dnes téma nie je o mne, ale o tom, ako si môžeme napísať vlastnú XML webovú službu založenú na protokole SOAP 1.2.

Dúfam, že po prečítaní témy budete vedieť:

  • napísať vlastnú serverovú implementáciu webovej aplikácie;
  • napísať vlastnú klientsku implementáciu webovej aplikácie;
  • napíšte svoj vlastný popis webovej služby (WSDL);
  • odoslať klientske polia rovnakého typu údajov na server.

Ako ste možno uhádli, všetky kúzla budú vykonané pomocou PHP a vstavaných tried SoapClient a SoapServer. Náš králik bude služba na odosielanie SMS správ.

1 Vyhlásenie o probléme

1.1 Hranice

Na začiatok navrhujem zaoberať sa výsledkom, ktorý dosiahneme na konci témy. Ako bolo oznámené vyššie, napíšeme službu na odosielanie SMS správ, presnejšie povedané, budeme prijímať správy z rôznych zdrojov cez protokol SOAP. Potom zvážime, v akej forme prídu na server. Proces radenia správ na ďalšie doručenie poskytovateľovi, žiaľ, z mnohých dôvodov presahuje rámec tohto príspevku.

1.2 Aké údaje zmeníme?

Skvelé, rozhodli sme sa pre hranice! Ďalším krokom, ktorý je potrebné urobiť, je rozhodnúť, aké údaje si budeme vymieňať medzi serverom a klientom. K tejto téme navrhujem nerozdeľovať vlasy príliš dlho a okamžite si odpovedať na hlavné otázky:

  • Aké minimálne údaje musia byť odoslané na server, aby bolo možné odoslať SMS správu účastníkovi?
  • Aké minimálne údaje musia byť odoslané zo servera, aby boli uspokojené potreby klienta?

Niečo mi hovorí, že na to musíte poslať nasledovné:

  • číslo mobilného telefónu a
  • text SMS správy.

V zásade tieto dve vlastnosti stačia na odoslanie, ale okamžite si predstavím prípad, keď k vám príde SMS s blahoželaním k narodeninám o 3:00 ráno alebo o 4! V tejto chvíli budem všetkým veľmi vďačná, že na mňa nezabudli! Preto pošleme aj na server a

  • dátum odoslania SMS správy.

Ďalšia vec, ktorú by som chcel poslať na server, je:

  • Typ správy.

Tento parameter nie je povinný, ale môže sa nám veľmi hodiť, ak potrebujeme šéfovi rýchlo povedať, koľkých našich klientov sme „potešili“ našimi novinkami, a načrtnúť k tomu aj krásnu štatistiku.

A predsa som na niečo zabudol! Ak sa trochu viac zamyslíme, stojí za zmienku, že klient môže na server poslať naraz jednu SMS správu alebo ich viacero. Inými slovami, jeden dátový paket môže obsahovať od jednej do nekonečna správ.

Výsledkom je, že na odoslanie SMS správy potrebujeme nasledujúce údaje:

  • Číslo mobilného telefónu,
  • text SMS správy,
  • čas odoslania SMS správy účastníkovi,
  • typ správy.

Odpovedali sme na prvú otázku, teraz musíme odpovedať na druhú otázku. A možno si dovolím trochu sa pomotať. Preto zo servera budeme posielať iba boolovské údaje, ktorých význam má nasledujúci význam:

  • TRUE – paket úspešne dorazil na server, prešiel autentifikáciou a zaradil sa do frontu na odoslanie poskytovateľovi SMS
  • FALSE – vo všetkých ostatných prípadoch

Týmto končíme popis problému! A nakoniec, poďme k zábavnej časti - poďme zistiť, aké zvláštne zviera je toto MYDLO!

2 Čo je SOAP?

Vo všeobecnosti som pôvodne nemal v pláne písať nič o tom, čo je SOAP a chcel som sa obmedziť na odkazy na webovú stránku w3.org s potrebnými špecifikáciami, ako aj odkazy na Wikipédiu. Ale na úplný záver som sa rozhodol napísať krátku poznámku o tomto protokole.

A svoj príbeh začnem tým, že tento protokol výmeny údajov patrí do podmnožiny protokolov založených na takzvanej paradigme RPC (Remote Procedure Call), ktorej protipólom je REST (Representational State Transfer). Viac si o tom môžete prečítať na Wikipédii, odkazy na články sú na samom konci témy. Z týchto článkov musíme pochopiť nasledovné: „Prístup RPC umožňuje použitie malého počtu sieťových zdrojov s veľkým počtom metód a zložitým protokolom. S prístupom REST je počet metód a zložitosť protokolu prísne obmedzené, čo znamená, že počet jednotlivých zdrojov môže byť veľký.“ To znamená, že vo vzťahu k nám to znamená, že na stránke v prípade prístupu RPC bude vždy jeden vstup (odkaz) na službu a aký postup zavolať na spracovanie prichádzajúcich údajov, ktoré prenášame spolu s údajmi, pričom s prístupom REST na našej stránke Stránka má veľa vstupov (odkazov), z ktorých každý prijíma a spracováva len určité údaje. Ak niekto, kto číta, vie ešte jednoduchšie vysvetliť rozdiel v týchto prístupoch, určite napíšte do komentárov!

Ďalšia vec, ktorú potrebujeme vedieť o SOAP je, že tento protokol používa rovnaké XML ako transport, čo je na jednej strane veľmi dobré, pretože Náš arzenál okamžite zahŕňa plnú silu balíka technológií založených na tomto značkovacom jazyku, konkrétne XML-Schema - jazyk na popis štruktúry XML dokumentu (vďaka Wikipédii!), ktorý umožňuje automatickú validáciu dát prijatých serverom. od klientov.

A tak teraz vieme, že SOAP je protokol používaný na implementáciu vzdialených volaní procedúr a používa XML ako transport! Ak si prečítate článok na Wikipédii, môžete sa z neho dozvedieť aj to, že ho možno použiť nad akýmkoľvek protokolom na aplikačnej úrovni, nielen v kombinácii s HTTP (žiaľ, v tejto téme budeme uvažovať iba o SOAP cez HTTP). A viete čo sa mi na tom všetkom páči najviac? Ak neexistujú žiadne dohady, potom vám dám nápovedu - MYDLO!... Stále žiadne odhady?... Naozaj ste čítali článok na Wikipédii?... Vo všeobecnosti vás nebudem ďalej mučiť. Preto prejdem priamo k odpovedi: „SOAP (z anglického Simple Object Access Protocol - jednoduchý protokol prístup k objektom; podľa špecifikácie 1.2)". Najpozoruhodnejšia vec na tomto riadku je v kurzíve! Neviem, aké závery ste z toho všetkého vyvodili, ale vidím nasledovné - keďže tento protokol sa v žiadnom prípade nedá nazvať "jednoduchým" (a zjavne s tým súhlasí aj w3), tak sa od verzie 1.2 prestal nejako dešifrovať ! A stalo sa známe ako SOAP, len SOAP, bodka.

Dobre, ospravedlňte ma, vzali sme to trochu bokom. Ako som už napísal, XML sa používa ako transport a pakety, ktoré cestujú medzi klientom a serverom, sa nazývajú SOAP obálky. Ak vezmete do úvahy všeobecnú štruktúru obálky, bude sa vám zdať veľmi povedomá, pretože... pripomína označenie stránky HTML. Má hlavnú časť - Obálka, ktorá zahŕňa sekcie Hlavička A Telo, alebo Chyba. IN Teloúdaje sa prenášajú a je to povinná časť obálky, pričom Hlavička je voliteľná. IN Hlavička môžu byť prenášané oprávnenia alebo akékoľvek iné údaje, ktoré priamo nesúvisia so vstupnými údajmi postupov webovej služby. O Chyba nie je potrebné povedať nič zvláštne, okrem toho, že to prichádza klientovi zo servera v prípade akýchkoľvek chýb.

Tu sa môj recenzný príbeh o protokole SOAP končí (na samotné obálky a ich štruktúru sa pozrieme podrobnejšie, keď sa ich náš klient a server konečne naučia prevádzkovať jeden na druhom) a začína nový – o spoločníkovi SOAP s názvom WSDL(Jazyk popisu webových služieb). Áno, áno, toto je práve tá vec, ktorá väčšinu z nás odrádza od snahy implementovať naše API na tento protokol. Výsledkom je, že zvyčajne znovu objavujeme naše koleso s JSON ako transport. Čo je teda WSDL? WSDL je jazyk na popis webových služieb a prístup k nim, založený na jazyku XML (c) Wikipedia. Ak vám táto definícia neobjasňuje celý posvätný význam tejto technológie, potom sa ju pokúsim opísať vlastnými slovami!

WSDL je navrhnutý tak, aby umožnil našim klientom normálnu komunikáciu so serverom. Na tento účel obsahuje súbor s príponou „*.wsdl“ nasledujúce informácie:

  • Aké menné priestory boli použité?
  • Aké dátové schémy boli použité?
  • Aké typy správ očakáva webová služba od klientov?
  • Ktoré údaje patria ku ktorým postupom webovej služby,
  • Aké procedúry webová služba obsahuje?
  • Ako by mal klient volať postupy webovej služby,
  • Na akú adresu sa majú posielať hovory zákazníkov?

Ako vidíte, tento súbor je celá webová služba. Zadaním adresy súboru WSDL v klientovi budeme vedieť všetko o akejkoľvek webovej službe! V dôsledku toho nemusíme vedieť absolútne nič o tom, kde sa samotná webová služba nachádza. Všetko, čo potrebujete vedieť, je umiestnenie jeho súboru WSDL! Čoskoro zistíme, že SOAP nie je také strašidelné, ako sa o ňom hovorí v ruských prísloviach.

3 Úvod do schémy XML

Teraz vieme veľa o tom, čo je SOAP, čo je v ňom a máme prehľad o technologickom balíku, ktorý ho obklopuje. Keďže SOAP je v prvom rade metóda interakcie medzi klientom a serverom a ako prenos sa používa značkovací jazyk XML, v tejto časti trochu porozumieme tomu, ako prebieha automatická validácia údajov pomocou schém XML.

Hlavnou úlohou diagramu je popísať štruktúru dát, ktoré budeme spracovávať. Všetky údaje v schémach XML sú rozdelené na jednoduché(skalárny) a komplexné(štruktúry) typy. Jednoduché typy zahŕňajú nasledujúce typy:

  • linka,
  • číslo,
  • boolovská hodnota,
  • dátum.

Niečo veľmi jednoduché, čo vo vnútri nemá žiadne rozšírenia. Ich antipódom sú zložité komplexné typy. Najjednoduchším príkladom zložitého typu, ktorý každému príde na myseľ, sú predmety. Napríklad kniha. Kniha pozostáva z vlastností: autora, názov, cena, ISBN číslo atď. A tieto vlastnosti môžu byť buď jednoduché typy, alebo zložité. A úlohou XML schémy je to popísať.

Odporúčam nezachádzať ďaleko a napísať schému XML pre našu SMS správu! Nižšie je uvedený xml popis SMS správy:

71239876543 Testovacia správa 2013-07-20T12:00:00 12

Náš komplexný typový diagram bude vyzerať takto:

Tento záznam znie takto: Máme premennú " správu"typ" Správa"a existuje komplexný typ s názvom " Správa", ktorý pozostáva zo sekvenčnej sady prvkov" telefón"typ reťazec, « text"typ reťazec, « dátum"typ Dátum Čas, « typu"typ desiatkový. Tieto typy sú jednoduché a sú už definované v popise schémy. Gratulujem! Práve sme napísali našu prvú schému XML!

Myslím si, že význam prvkov " element"A" komplexný typ„Všetko je vám už viac-menej jasné, takže sa im už viac nebudeme venovať a prejdime rovno na skladateľský prvok“ sekvencie" Keď použijeme prvok skladateľ " sekvencie„Informujeme vás, že prvky, ktoré obsahuje, musia byť vždy umiestnené v poradí uvedenom v diagrame a všetky sú povinné. Ale nezúfajte! V schémach XML sú ďalšie dva prvky skladateľa: " výber"A" všetky" skladateľ" výber" oznamuje, že musí byť v ňom uvedený jeden z prvkov, a skladateľ" všetky» – ľubovoľná kombinácia uvedených prvkov.

Ako si pamätáte, v prvej časti témy sme sa zhodli, že v balíku je možné prenášať SMS správy od jednej do nekonečna. Preto navrhujem pochopiť, ako sú takéto údaje deklarované v schéme XML. Všeobecná štruktúra balíka môže vyzerať takto:

71239876543 Testovacia správa 1 2013-07-20T12:00:00 12 71239876543 Testovacia správa N 2013-07-20T12:00:00 12

Diagram pre takýto komplexný typ bude vyzerať takto:

Prvý blok obsahuje známu deklaráciu komplexného typu „ Správa" Ak ste si všimli, potom v každom jednoduchom type obsiahnutom v " Správa", boli pridané nové objasňujúce atribúty " minOccurs"A" maxOccurs" Ako ste mohli uhádnuť z názvu, prvý ( minOccurs) označuje, že táto sekvencia musí obsahovať aspoň jeden prvok typu " telefón», « text», « dátum"A" typu“, zatiaľ čo ďalší ( maxOccurs) nám deklaruje, že v našej sekvencii je najviac jeden takýto prvok. Výsledkom je, že keď píšeme svoje vlastné schémy pre akékoľvek údaje, máme najširšiu možnosť výberu, ako ich nakonfigurovať!

Druhý blok diagramu deklaruje prvok " messageList"typ" Zoznam správ" Je jasné, že" Zoznam správ"je komplexný typ, ktorý obsahuje aspoň jeden prvok" správu“, ale maximálny počet takýchto prvkov nie je obmedzený!

4 Napíšte svoj WSDL

Pamätáte si, že WSDL je naša webová služba? Dúfam, že si pamätáš! Keď ho napíšeme, pobeží na ňom naša malá webová služba. Preto navrhujem, aby ste sa nemotali.

Vo všeobecnosti, aby nám všetko správne fungovalo, musíme klientovi preniesť WSDL súbor so správnym MIME typom. Ak to chcete urobiť, musíte zodpovedajúcim spôsobom nakonfigurovať váš webový server, konkrétne nastaviť typ MIME pre súbory s príponou „*.wsdl“ na nasledujúci riadok:

Aplikácia/wsdl+xml

Ale v praxi som zvyčajne posielal hlavičku HTTP cez PHP “ text/xml»:

Hlavička("Typ obsahu: text/xml; charset=utf-8");

a všetko fungovalo skvele!

Chcem vás hneď varovať, že naša jednoduchá webová služba bude mať dosť pôsobivý popis, takže sa nezľaknite, pretože... Väčšina textu je povinná voda a po jeho napísaní ho môžete neustále kopírovať z jednej webovej služby do druhej!

Keďže WSDL je XML, musíte o tom písať priamo v prvom riadku. Koreňový prvok súboru by sa mal vždy volať " definície»:

Typicky sa WSDL skladá zo 4-5 hlavných blokov. Hneď prvým blokom je definícia webovej služby alebo inak povedané vstupného bodu.

Hovorí sa tu, že máme službu s názvom – “ Služba SMS" V zásade všetky názvy v súbore WSDL môžete zmeniť na čokoľvek chcete, pretože nehrajú absolútne žiadnu rolu.

Potom oznamujeme, že v našej webovej službe „ Služba SMS" existuje vstupný bod ("port") s názvom " SmsServicePort" Práve do tohto vstupného bodu budú odoslané všetky požiadavky od klientov na server. A uveďte v prvku „ adresu» odkaz na súbor obsluhy, ktorý bude akceptovať požiadavky.

Keď sme definovali webovú službu a určili jej vstupný bod, musíme na ňu naviazať podporované postupy:

K tomu vypíše, ktoré operácie a v akej forme sa budú volať. Tie. pre prístav" SmsServicePort"väzba je definovaná pod názvom" SmsServiceBinding", ktorý má typ hovoru " rpc"a HTTP sa používa ako prenosový protokol. Preto sme tu naznačili, že uskutočníme volanie RPC cez HTTP. Potom popíšeme, ktoré postupy ( prevádzka) sú podporované vo webovej službe. Budeme podporovať iba jeden postup – “ poslaťSms" Prostredníctvom tohto postupu budú naše úžasné správy odoslané na server! Po vyhlásení postupu je potrebné uviesť, v akej forme sa budú údaje prenášať. V tomto prípade je uvedené, že sa použijú štandardné obálky SOAP.

Potom musíme postup spojiť so správami:

Aby sme to dosiahli, špecifikujeme, že naša väzba je typu " SmsServicePortType"a v živle" portType„Názvom rovnakého typu označujeme viazanie procedúr na správy. Prichádzajúca správa (z klienta na server) sa teda bude nazývať „ odoslaťSmsRequest"a odchádzajúce (zo servera na klienta) " sendSmsResponse" Rovnako ako všetky mená vo WSDL, názvy prichádzajúcich a odchádzajúcich správ sú ľubovoľné.

Teraz nám treba popísať samotné správy, t.j. prichádzajúce a odchádzajúce:

Za týmto účelom pridáme prvky " správu"s menami" odoslaťSmsRequest"A" sendSmsResponse“ resp. V nich uvádzame, že vstupom by mala byť obálka, ktorej štruktúra zodpovedá typu údajov " Žiadosť" Potom sa zo servera vráti obálka obsahujúca typ údajov - “ odpoveď».

Teraz musíme urobiť len málo - pridať popis týchto typov do nášho súboru WSDL! A ako podľa vás WSDL popisuje prichádzajúce a odchádzajúce dáta? Myslím, že ste už všetko dávno pochopili a povedali ste si, že pomocou schém XML! A budete mať úplnú pravdu!

Môžete nám zablahoželať! Náš prvý WSDL bol napísaný! A sme o krok bližšie k dosiahnutiu nášho cieľa.
Ďalej sa pozrieme na to, čo nám PHP poskytuje na vývoj vlastných distribuovaných aplikácií.

5 Náš prvý SOAP server

Predtým som napísal, že na vytvorenie servera SOAP v PHP použijeme vstavanú triedu SoapServer. Aby všetky ďalšie akcie prebehli rovnako ako u mňa, budete musieť trochu upraviť svoje PHP. Aby sme boli ešte presnejší, musíte sa uistiť, že máte nainštalované rozšírenie „php-soap“. Ako ho nainštalovať na webový server je najlepšie si prečítať na oficiálnej stránke PHP (pozri zoznam referencií).

Keď bude všetko nainštalované a nakonfigurované, budeme musieť vytvoriť súbor v koreňovom priečinku vášho hostingu “ smsservice.php» s nasledujúcim obsahom:

setClass("SoapSmsGateWay"); //Spustenie servera $server->handle();

Dúfam, že nie je potrebné vysvetľovať, čo je nad riadkom s funkciou „ini_set“. Pretože tam sa určí, ktoré HTTP hlavičky budeme posielať zo servera klientovi a prostredie je nakonfigurované. V riadku s „ini_set“ zakážeme ukladanie súboru WSDL do vyrovnávacej pamäte, aby sa naše zmeny v ňom okamžite prejavili na klientovi.

Teraz prichádzame na server! Ako vidíte, celý SOAP server zaberá iba tri riadky! Na prvom riadku vytvoríme novú inštanciu objektu SoapServer a jej konštruktorovi odovzdáme adresu nášho WSDL popisu webovej služby. Teraz vieme, že sa bude nachádzať v koreňovom adresári hostingu v súbore so samovysvetľujúcim názvom „ smsservice.wsdl.php" V druhom riadku hovoríme SOAP serveru, ktorú triedu je potrebné stiahnuť, aby spracoval obálku prijatú od klienta a vrátil obálku s odpoveďou. Ako ste možno uhádli, práve v tejto triede bude opísaná naša jediná metóda poslaťSms. Na treťom riadku spustíme server! To je všetko, náš server je pripravený! S čím nám všetkým blahoželám!

Teraz musíme vytvoriť súbor WSDL. Ak to chcete urobiť, môžete buď jednoducho skopírovať jeho obsah z predchádzajúcej časti, alebo si ho trochu „vymodelovať“:

"; ?> /" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http:// schemas.xmlsoap.org/wsdl/http/" name="SmsWsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"> /"> /smsservice.php" />

V tejto fáze by sme mali byť s výsledným serverom úplne spokojní, pretože Môžeme zaznamenať prichádzajúce obálky a potom pokojne analyzovať prichádzajúce údaje. Aby sme mohli prijímať čokoľvek na server, potrebujeme klienta. Tak poďme na to!

6 SOAP klient na ceste

V prvom rade si musíme vytvoriť súbor, do ktorého budeme klienta zapisovať. Ako obvykle ho vytvoríme v koreňovom adresári hostiteľa a nazveme ho „ klient.php“ a dovnútra napíšeme nasledovné:

messageList = new MessageList(); $req->messageList->message = new Message(); $req->messageList->message->phone = "79871234567"; $req->messageList->message->text = "Testovacia správa 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->message->type = 15; $client = new SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($client->sendSms($req));

Popíšme naše predmety. Keď sme písali WSDL, popisoval tri entity pre obálku prichádzajúcu na server: Žiadosť, Zoznam správ A Správa. Podľa toho triedy Žiadosť, Zoznam správ A Správa sú odrazom týchto entít v našom PHP skripte.

Keď máme definované objekty, musíme vytvoriť objekt ( $req), ktorý odošleme na server. Potom prídu dve pre nás najcennejšie línie! Náš SOAP klient! Verte tomu alebo nie, stačí to na to, aby náš server začal prijímať správy od klienta, ako aj na to, aby ich náš server úspešne prijímal a spracovával! V prvom z nich vytvoríme inštanciu triedy SoapClient a jeho konštruktorovi odovzdáme adresu umiestnenia súboru WSDL a v parametroch výslovne uvedieme, že budeme pracovať s protokolom SOAP verzie 1.2. Na ďalšom riadku zavoláme metódu poslaťSms objekt $klient a okamžite zobraziť výsledok v prehliadači.
Poďme to spustiť a uvidíme, čo sme nakoniec dostali!

Zo servera sa mi vrátil nasledujúci objekt:

Object(stdClass) public "status" => boolean true

A to je skvelé, pretože... Teraz s istotou vieme, že náš server funguje a nielenže funguje, ale môže klientovi aj vrátiť niektoré hodnoty!

Teraz sa pozrime na denník, ktorý opatrne vedieme na strane servera! V jeho prvej časti vidíme nespracované dáta, ktoré prišli na server:

79871234567 Testovacia správa 1 2013-07-21T15:00:00.26 15

Toto je obálka. Teraz viete, ako to vyzerá! Je však nepravdepodobné, že by nás to zaujímalo neustále, takže deserializujme objekt zo súboru denníka a uvidíme, či je všetko v poriadku:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => string "79871234567" (dĺžka=11) public "text" => string "Testovacia správa 1 " (dĺžka=37) public "date" => reťazec "2013-07-21T15:00:00.26" (dĺžka=22) public "type" => reťazec "15" (dĺžka=2)

Ako vidíte, objekt bol deserializovaný správne, k čomu nám všetkým chcem zablahoželať! Nabudúce nás čaká niečo zaujímavejšie! Klientovi totiž pošleme na server nie len jednu SMS správu, ale celý balík (presnejšie tri)!

7 Odosielanie zložitých objektov

Zamyslime sa nad tým, ako môžeme preniesť na server množstvo správ v jednom pakete? Pravdepodobne najjednoduchším spôsobom by bolo usporiadať pole v prvku messageList! Poďme to spraviť:

// vytvorenie objektu na odoslanie na server $req = new Request(); $req->messageList = new MessageList(); $msg1 = nová správa (); $msg1->telefón = "79871234567"; $msg1->text = "Testovacia správa 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->typ = 15; $msg2 = nová správa (); $msg2->phone = "79871234567"; $msg2->text = "Testovacia správa 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->typ = 16; $msg3 = nová správa (); $msg3->telefón = "79871234567"; $msg3->text = "Testovacia správa 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->typ = 17; $req->messageList->message = $msg1; $req->messageList->message = $msg2; $req->messageList->message = $msg3;

Naše protokoly naznačujú, že od klienta bol prijatý nasledujúci paket:

79871234567 Testovacia správa 1 2013-07-21T15:00:00.26 15 79871234567 Testovacia správa 2 2014-08-22T16:01:10 16 79871234567 Testovacia správa 3 2014-08-22T16:01:10 17

Aký nezmysel, hovoríš? A v istom zmysle budete mať pravdu, pretože... Hneď ako sme sa dozvedeli, že objekt odišiel z klienta, prišiel na náš server v absolútne rovnakej podobe vo forme obálky. Pravda, SMS správy neboli serializované v XML tak, ako sme potrebovali – museli byť zabalené do prvkov správu, nie v Struct. Teraz sa pozrime, v akej forme takýto objekt prichádza do metódy poslaťSms:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "Struct" => pole (size=3) 0 => object(stdClass) public "phone" => string "79871234567" (dĺžka=11) public "text" => reťazec "Testovacia správa 1" (dĺžka=37) public "dátum" => reťazec "2013-07-21T15:00:00.26" (dĺžka=22) public " typ" => reťazec "15" (dĺžka=2) 1 => objekt (štandardná trieda) verejný "telefón" => reťazec "79871234567" (dĺžka=11) verejný "text" => reťazec "Testovacia správa 2" (dĺžka= 37) public "date" => string "2014-08-22T16:01:10" (dĺžka=19) public "type" => string "16" (dĺžka=2) 2 => objekt (stdClass) public "telefón " => reťazec "79871234567" (dĺžka=11) public "text" => reťazec "Testovacia správa 3" (dĺžka=37) public "dátum" => reťazec "2014-08-22T16:01:10" (dĺžka= 19) verejný "typ" => reťazec "17" (dĺžka = 2)

Čo nám toto poznanie dáva? Iba to, že cesta, ktorú sme zvolili, nie je správna a nedostali sme odpoveď na otázku - „Ako môžeme získať správnu štruktúru údajov na serveri?“ Navrhujem však nezúfať a pokúsiť sa previesť naše pole na typ objekt:

$req->messageList->message = (objekt)$req->messageList->message;

V tomto prípade dostaneme ďalšiu obálku:

79871234567 Testovacia správa 1 2013-07-21T15:00:00.26 15 79871234567 Testovacia správa 2 2014-08-22T16:01:10 16 79871234567 Testovacia správa 3 2014-08-22T16:01:10 17

Vstúpil do metódy poslaťSms objekt má nasledujúcu štruktúru:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "BOGUS" => pole (veľkosť=3) 0 => objekt (stdClass) public "phone" => reťazec "79871234567" (dĺžka=11) public "text" => reťazec "Testovacia správa 1" (dĺžka=37) public "dátum" => reťazec "2013-07-21T15:00:00.26" (dĺžka=22) public " typ" => reťazec "15" (dĺžka=2) 1 => objekt (štandardná trieda) verejný "telefón" => reťazec "79871234567" (dĺžka=11) verejný "text" => reťazec "Testovacia správa 2" (dĺžka= 37) public "date" => string "2014-08-22T16:01:10" (dĺžka=19) public "type" => string "16" (dĺžka=2) 2 => objekt (stdClass) public "telefón " => reťazec "79871234567" (dĺžka=11) public "text" => reťazec "Testovacia správa 3" (dĺžka=37) public "dátum" => reťazec "2014-08-22T16:01:10" (dĺžka= 19) verejný "typ" => reťazec "17" (dĺžka = 2)

Pokiaľ ide o mňa, „súčet sa nezmení zmenou miesta výrazov“ (c). Čo PODVODNÝ, Čo Struct– ešte sme nedosiahli náš cieľ! A aby sme to dosiahli, musíme sa postarať o to, aby sa namiesto týchto nezrozumiteľných mien zobrazovalo to naše rodné správu. Ale autor zatiaľ nevie, ako to dosiahnuť. Preto jediné, čo môžeme urobiť, je zbaviť sa nadbytočnej nádoby. Inými slovami, teraz sa uistíme, že namiesto toho správu sa stal PODVODNÝ! Ak to chcete urobiť, zmeňte objekt takto:

// vytvorenie objektu na odoslanie na server $req = new Request(); $msg1 = nová správa (); $msg1->telefón = "79871234567"; $msg1->text = "Testovacia správa 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->typ = 15; $msg2 = nová správa (); $msg2->phone = "79871234567"; $msg2->text = "Testovacia správa 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->typ = 16; $msg3 = nová správa (); $msg3->telefón = "79871234567"; $msg3->text = "Testovacia správa 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->typ = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (objekt)$req->messageList;

Čo ak budeme mať šťastie a z diagramu vypadne správny názov? Ak to chcete urobiť, pozrime sa na doručenú obálku:

79871234567 Testovacia správa 1 2013-07-21T15:00:00.26 15 79871234567 Testovacia správa 2 2014-08-22T16:01:10 16 79871234567 Testovacia správa 3 2014-08-22T16:01:10 17

Áno, zázrak sa nestal! PODVODNÝ- nevyhráme! Poď do poslaťSms objekt v tomto prípade bude vyzerať takto:

Object(stdClass) public "messageList" => object(stdClass) public "BOGUS" => pole (size=3) 0 => object(stdClass) public "phone" => string "79871234567" (dĺžka=11) public " text" => reťazec "Testovacia správa 1" (dĺžka=37) public "dátum" => reťazec "2013-07-21T15:00:00.26" (dĺžka=22) public "typ" => reťazec "15" (dĺžka =2) 1 => objekt (štandardná trieda) verejný "telefón" => reťazec "79871234567" (dĺžka=11) verejný "text" => reťazec "Testovacia správa 2" (dĺžka=37) verejný "dátum" => reťazec " 2014-08-22T16:01:10" (dĺžka=19) public "type" => reťazec "16" (dĺžka=2) 2 => objekt (stdClass) verejný "telefón" => reťazec "79871234567" (dĺžka= 11) public "text" => string "Test message 3" (dĺžka=37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string " 17" (dĺžka = 2)

Ako sa hovorí – „Takmer“! Na túto (trochu smutnú) poznámku navrhujem pomaly veci zabaliť a vyvodiť pre seba nejaké závery.

8 Záver

Konečne sme sa sem dostali! Poďme zistiť, čo môžete urobiť teraz:

  • môžete napísať súbor WSDL potrebný pre vašu webovú službu;
  • môžete jednoducho napísať vlastného klienta, ktorý dokáže komunikovať so serverom cez SOAP;
  • môžete si napísať svoj vlastný server, ktorý komunikuje s vonkajším svetom cez SOAP;
  • z vášho klienta môžete posielať polia rovnakého typu objektov na server (s určitými obmedzeniami).

Počas nášho malého výskumu sme tiež urobili niekoľko objavov:

  • natívna trieda SoapClient nesprávne serializuje dátové štruktúry rovnakého typu v XML;
  • pri serializácii poľa do XML sa vytvorí ďalší prvok s názvom Struct;
  • pri serializácii objektu do XML sa vytvorí ďalší prvok s názvom PODVODNÝ;
  • PODVODNÝ menšie zlo ako Struct vďaka tomu, že obálka je kompaktnejšia (do XML hlavičky obálky sa nepridávajú ďalšie menné priestory);
  • Žiaľ, trieda SoapServer automaticky neoveruje dáta obálky pomocou našej XML schémy (možno to nerobia ani iné servery).

Lyrická časť.

Predstavte si, že ste implementovali alebo implementujete určitý systém, ktorý by mal byť prístupný zvonku. Tie. existuje určitý server, s ktorým musíte komunikovať. Napríklad webový server.

Tento server môže vykonávať mnoho akcií, pracovať s databázou, vykonávať niektoré požiadavky tretích strán na iné servery, robiť nejaké výpočty atď. žiť a prípadne sa vyvíjať podľa scenára, ktorý je mu známy (t. j. podľa scenára vývojárov). Pre človeka nie je zaujímavé komunikovať s takýmto serverom, pretože nemusí byť schopný/nechce poskytnúť pekné stránky s obrázkami a iným užívateľsky príjemným obsahom. Je napísaná a funguje tak, aby fungovala a poskytovala údaje, keď je o to požiadaná, bez obáv, že je čitateľná človekom, klient si s ňou poradí sám.

Iné systémy, ktoré pristupujú na tento server, už môžu nakladať s údajmi prijatými z tohto servera podľa vlastného uváženia - spracovávať, zhromažďovať, vydávať svojim klientom atď.

Jednou z možností komunikácie s takýmito servermi je SOAP. Protokol na výmenu správ SOAP xml.

Praktická časť.

Webová služba (to je názov toho, čo server poskytuje a čo využívajú klienti) umožňuje komunikovať so serverom pomocou jasne štruktúrovaných správ. Faktom je, že webová služba neprijíma žiadne údaje. Webová služba odpovie chybou na každú správu, ktorá nie je v súlade s pravidlami. Chyba bude mimochodom aj vo forme xml s jasnou štruktúrou (čo nie je pravda o texte správy).

WSDL (Web Services Description Language). Pravidlá, podľa ktorých sa skladajú správy pre webovú službu, sú popísané aj pomocou xml a majú tiež jasnú štruktúru. Tie. Ak webová služba poskytuje možnosť volať metódu, musí klientom umožniť vedieť, aké parametre sa pre túto metódu používajú. Ak webová služba očakáva reťazec pre metódu1 ako parameter a reťazec by mal mať názov Param1, potom budú tieto pravidlá špecifikované v popise webovej služby.

Ako parametre možno odovzdať nielen jednoduché typy, ale aj objekty a kolekcie objektov. Opis objektu spočíva v popise každého komponentu objektu. Ak sa objekt skladá z viacerých polí, potom je každé pole popísané, jeho typ, názov (aké sú možné hodnoty). Polia môžu byť aj komplexného typu a tak ďalej, až kým popis typov nekončí jednoduchými – reťazec, boolean, číslo, dátum... Niektoré špecifické typy sa však môžu ukázať ako jednoduché, dôležité je, aby klienti dokáže pochopiť, aké hodnoty môžu obsahovať.

Klientom stačí poznať adresu URL webovej služby, wsdl bude vždy nablízku, z ktorého si môžete urobiť predstavu o metódach a ich parametroch, ktoré táto webová služba poskytuje.

Aké sú výhody všetkých týchto zvončekov a píšťaliek:

  • Vo väčšine systémov sa popis metód a typov vyskytuje automaticky. Tie. programátor na serveri potrebuje len povedať, že túto metódu možno zavolať cez webovú službu a popis wsdl sa vygeneruje automaticky.
  • Popis, ktorý má jasnú štruktúru, je čitateľný pre každého mydlového klienta. Tie. bez ohľadu na webovú službu klient pochopí, aké údaje webová služba prijíma. Pomocou tohto popisu si klient môže vybudovať vlastnú vnútornú štruktúru tried objektov, tzv. väzba" a. Výsledkom je, že programátor používajúci webovú službu musí napísať niečo ako (pseudokód):

    NewUser:=TSoapUser.Create("Vasya","Pupkin","admin"); mydlo.AddUser(NewUser);

  • Automatická validácia.

    • xml overenie. xml musí mať správny tvar. Neplatný xml - okamžite chyba klientovi, nech si to vyrieši.
    • validácia schémy. xml musí mať určitú štruktúru. xml nezodpovedá schéme - okamžite chyba klientovi, nech si to vyrieši.
    • Overenie údajov vykonáva mydlový server tak, aby typy údajov a obmedzenia zodpovedali popisu.
  • Autorizáciu a autentifikáciu je možné realizovať pomocou samostatnej metódy. natívne. alebo pomocou autorizácie http.
  • Webové služby môžu fungovať ako cez mydlový protokol, tak aj cez http, teda cez get requesty. To znamená, že ak sú parametre jednoduché údaje (bez štruktúry), potom môžete jednoducho zavolať obvyklé get www.site.com/users.asmx/GetUser?Name=Vasia alebo post. Nie je to však všade a nie vždy.
  • ...pozri na Wikipedii

Existuje tiež veľa nevýhod:

  • Neprimerane veľká veľkosť správy. No, samotná povaha xml je taká, že formát je nadbytočný, čím viac značiek, tým viac zbytočných informácií. Plus mydlo dodáva jeho redundanciu. Pre intranetové systémy je problém s návštevnosťou menej akútny ako pre internet, takže mydlo pre lokálne siete je viac žiadané, najmä Sharepoint má webovú službu, s ktorou môžete úspešne (a s určitými obmedzeniami) komunikovať.
  • Automatická zmena popisu webovej služby môže zlomiť všetkých klientov. No, je to tak pre každý systém, ak nie je podporovaná spätná kompatibilita so starými metódami, všetko spadne...
  • Nie mínus, ale nevýhoda. Všetky volania metód musia byť atomické. Napríklad pri práci s databázou môžeme spustiť transakciu, vykonať niekoľko dotazov, potom rollback alebo commit. V mydle nie sú žiadne transakcie. Jedna prosba, jedna odpoveď, rozhovor sa skončil.
  • Zaoberať sa popisom toho, čo je na strane servera (je všetko popísané správne?) a čo na klientovi (čo mi tu bolo popísané?), môže byť dosť náročné. Niekoľkokrát som to musel riešiť s klientskou stranou a presviedčať programátora servera, že jeho dáta sú popísané nesprávne, no on z toho vôbec ničomu nerozumel, pretože automatické generovanie a on by nemal, to je vec softvér. A chyba bola, prirodzene, v kóde metódy, programátor to jednoducho nevidel.
  • Prax ukazuje, že vývojári webových služieb sú strašne ďaleko od ľudí, ktorí tieto webové služby používajú. V reakcii na akúkoľvek požiadavku (platnú zvonku) môže prísť nepochopiteľná chyba „Chyba 5. Všetko je zlé“. Všetko záleží na svedomí vývojárov :)
  • Som si istý, že si stále niečo nepamätám...

Ako príklad je tu otvorená webová služba belavia:

  • http://86.57.245.235/TimeTable/Service.asmx - vstupný bod, je tam aj textový popis metód pre vývojárov tretích strán.
  • http://86.57.245.235/TimeTable/Service.asmx?WSDL - wsdl popis metód a typov prijatých a vrátených dát.
  • http://86.57.245.235/TimeTable/Service.asmx?op=GetAirportsList - popis konkrétnej metódy s príkladom typu xml požiadavky a xml odpovede.

Môžete manuálne vytvoriť a odoslať požiadavku, ako napríklad:

POST /TimeTable/Service.asmx HTTP/1.1 Hostiteľ: 86.57.245.235 Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://webservices.belavia.by/GetAirportsList" ru

odpoveď príde:

HTTP/1.1 200 OK Dátum: Po, 30. september 2013 00:06:44 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Verzia: 4.0.30319 Cache-Control: súkromná, max. -age=0 Typ obsahu: text/xml; charset=utf-8 Obsah-Dĺžka: 2940

PS Predtým bola otvorená webová služba Aeroflot, ale potom, čo 1C pridal podporu mydla do 8ku, partia beta testerov 1C ju úspešne nainštalovala. Teraz sa tam niečo zmenilo (adresu neviem, v prípade záujmu si ju môžete vyhľadať).
ZZY Vylúčenie zodpovednosti. Hovoril na každodennej úrovni. Môžete kopať.

Nebudem sa venovať otázke, čo to je webové služby a prečo sú potrebné. Na internete je veľa článkov na túto tému. Pokúsim sa len stručne ukázať, aké jednoduché je vytvoriť klienta pre akúkoľvek webovú službu v PHP.

nastavenie

Na použitie SOAP v php je potrebné pripojiť modul SOAP (súčasť distribúcie php5). V systéme Windows sa to robí jednoducho - musíte pridať (konkrétne pridať, keďže tento riadok tam nie je len zakomentovaný, úplne chýba) v php.ini:
extension=php_soap.dll

Ak máte php nainštalovaný ako modul, nezabudnite reštartovať server.


Vytvorenie klienta SOAP z dokumentu WSDL

Vytvorenie klienta SOAP sa zvyčajne uskutočňuje podľa WSDL dokument, čo je XML dokument v špecifickom formáte, ktorý plne popisuje konkrétnu webovú službu. Podrobnosti o WSDL nájdete na webovej stránke konzorcia W3C - http://www.w3.org/TR/2005/WD-wsdl20-soap11-binding-20050510/.

Hlavná vec, ktorú potrebujete vedieť, aby ste mohli zostaviť klienta pre webovú službu, je poznať adresu URL jej dokumentu WSDL.
Vezmime si napríklad webovú službu „Výmenný kurz“ z xmethods.com. Adresa tejto webovej služby, ktorá vám umožňuje prijímať výmenné kurzy online, je http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl.

Druhým dôležitým bodom je, že z popisu webovej služby je potrebné získať informácie o tom, aké metódy táto služba poskytuje a aké parametre jej máme odovzdať ako vstupné hodnoty (veľmi podobné volaniu bežnej PHP funkcie alebo triedy metóda). Tieto informácie sú zvyčajne obsiahnuté v popise služby na jej webovej stránke. Naša webová služba na získavanie výmenných kurzov poskytuje metódu getRate(), ktorej sa kódy mien odovzdávajú ako argumenty.

A nakoniec je dôležité vedieť, čo očakávať ako odpoveď: koľko hodnôt, aký typ atď. Dá sa to zistiť aj z popisu.
A v dôsledku toho sa kód ukazuje ako veľmi jednoduchý a kompaktný, takmer elementárny:

// Používanie webovej služby
// "Výmenný kurz" z xmethods.com

// Vytvorenie klienta SOAP z dokumentu WSDL
$client = new SoapClient("http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl");

// Pošlite požiadavku SOAP a získajte výsledok
$vysledok = $klient->getRate("us", "rusko");

Echo 'Aktuálny výmenný kurz dolára: ', $výsledok, 'ruble';
?>

Ako vidíte z kódu, musíte odovzdať URL WSDL dokumentu do konštruktora triedy SoapClient a prijať objekt na prácu s požadovanou webovou službou. Potom sa zavolá metóda tohto objektu, ktorej názov je zhodný s názvom samotnej metódy webovej služby. Táto metóda vráti výsledok, ktorý chceme.

Tento jednoduchý príklad teda ilustruje princíp budovania SOAP klienta pre webové služby v PHP. V reálnej aplikácii je však stále čo riešiť, najmä to, že pri volaní webovej služby môže byť dočasne nedostupná alebo môže vrátiť chybu. Jednoznačne to navrhuje použiť blok skúsiť/chytiť/hodiť :)

(PHP 5 >= 5.0.1)

SoapClient::SoapClient — Konštruktor SoapClient

Parametre

wsdl

URI z WSDL súbor alebo NULOVÝ ak pracujete v non-WSDL režim.

Počas vývoja môže byť ukladanie do vyrovnávacej pamäte WSDL zakázané použitím soap.wsdl_cache_ttl php.ini nastavenie inak zmeny vykonané v súbore WSDL nebudú mať žiadny účinok, kým soap.wsdl_cache_ttl vypršala platnosť.

možnosti

Množstvo možností. Ak pracujete v režime WSDL, tento parameter je voliteľný. Ak pracujete v režime bez WSDL, umiestnenie a uri musia byť nastavené možnosti, kde umiestnenie je adresa URL servera SOAP, na ktorý sa má odoslať požiadavka, a uri je cieľový menný priestor služby SOAP.

The štýl a použitie možnosti fungujú iba v režime bez WSDL. V režime WSDL pochádzajú zo súboru WSDL.

The mydlo_verzia voľba určuje, či sa má použiť klient SOAP 1.1 (predvolené) alebo SOAP 1.2.

Pre HTTP autentifikáciu, Prihlásiť sa a heslo možnosti možno použiť na dodanie poverení. Pre vytvorenie pripojenia HTTP cez proxy server, možnosti proxy_host, proxy_port, proxy_login a proxy_password sú tiež k dispozícii. Na použitie autentifikácie klientskeho certifikátu HTTPS local_cert a prístupová fráza možnosti. Overenie môže byť poskytnuté v Overenie možnosť. Spôsob overenia môže byť buď SOAP_AUTHENTICATION_BASIC(predvolené) alebo SOAP_AUTHENTICATION_DIGEST.

The kompresia možnosť umožňuje použiť kompresiu HTTP SOAP požiadaviek a odpovedí.

The kódovanie voľba definuje interné kódovanie znakov. Táto voľba nemení kódovanie SOAP požiadaviek (vždy je to utf-8), ale konvertuje naň reťazce.

The stopa možnosť umožňuje sledovanie požiadavky, aby bolo možné spätne vysledovať chyby. Toto je predvolene FALSE

The triedna mapa možno použiť na mapovanie niektorých typov WSDL na triedy PHP. Táto voľba musí byť pole s typmi WSDL ako kľúčmi a názvami tried PHP ako hodnotami.

Nastavenie booleovskej hodnoty stopa voľba umožňuje použitie metód SoapClient->__getLastRequest , SoapClient->__getLastRequestHeaders , SoapClient->__getLastResponse a SoapClient->__getLastResponseHeaders .

The výnimky voľba je boolovská hodnota definujúca, či mydlové chyby spôsobia výnimky typu SoapFault .

The spojenie vypršalo definuje časový limit v sekundách pre pripojenie k službe SOAP. Táto možnosť nedefinuje časový limit pre služby s pomalými odozvami. Ak chcete obmedziť čas čakania na dokončenie hovorov, je k dispozícii nastavenie default_socket_timeout.

The typovú mapu voľba je pole typových mapovaní. Mapovanie typov je pole s kľúčmi názov_typu, type_ns(URI menného priestoru), from_xml(spätné volanie akceptujúce jeden parameter reťazca) a to_xml(spätné volanie akceptujúce jeden parameter objektu).

The cache_wsdl možnosť je jednou z WSDL_CACHE_NONE, WSDL_CACHE_DISK, WSDL_CACHE_MEMORY alebo WSDL_CACHE_BOTH.

The user_agent voľba určuje reťazec, ktorý sa má použiť User-Agent hlavička.

The stream_context možnosť je pre kontext .

The Vlastnosti možnosť je bitová maska SOAP_SINGLE_ELEMENT_ARRAYS, SOAP_USE_XSI_ARRAY_TYPE, SOAP_WAIT_ONE_WAY_CALLS.

The udržať nažive voľba je boolovská hodnota definujúca, či sa má odoslať Spojenie: Keep-Alive hlavička resp Pripojenie: zatvorte .

Denník zmien

Verzia Popis
5.4.0 Nový udržať nažive možnosť.

Príklady

Príklad #1 SoapClient::SoapClient() príklad

$klient = new SoapClient("some.wsdl");

$klient = nový SoapClient ("some.wsdl" , array("soap_version" => SOAP_1_2 ));

$client = nový SoapClient ("some.wsdl" , array("login" => "some_name" ,
"heslo" => "nejake_heslo" ));

$client = nový SoapClient ("some.wsdl" , array("proxy_host" => "localhost" ,
"proxy_port" => 8080 ));

$client = nový SoapClient ("some.wsdl" , array("proxy_host" => "localhost" ,
"proxy_port" => 8080,
"proxy_login" => "nejake_meno" ,
"proxy_password" => "nejake_heslo" ));

$client = nový SoapClient ("some.wsdl" , array("local_cert" => "cert_key.pem" ));

$client = nový SoapClient (null , array("location" =>
"uri" => "http://test-uri/" ));

$client = nový SoapClient (null , array("location" => "http://localhost/soap.php" ,
"uri" => "http://test-uri/" ,
"style" => SOAP_DOCUMENT ,
"použitie" => SOAP_LITERAL ));

$client = new SoapClient("some.wsdl" ,
array("kompresia" => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP ));

$server = new SoapClient ("some.wsdl" , array("encoding" => "ISO-8859-1" ));

trieda MyBook(
verejný $titul ;
verejný $autor ;
}

$server = new SoapClient ("books.wsdl" , array("classmap" => array("book" => "MyBook" )));

?>

Chris Gunawardena

Ak chcete monitorovať volania SOAP do a zo servera unix:

Sudo tcpdump -nn -vv -A -s 0 -i eth0 dst alebo src hostiteľ xxx.xxx.xxx.xxx a port 80

A vždy používajte "cache_wsdl" => WSDL_CACHE_NONE

svenr at selfhtml dot org

Možnosť „classmap“ je vlastne mapovanie z „ComplexType“ používaného v rámci SOAP na vaše triedy PHP.

Nezamieňajte si názvy značiek XML vrátené pre vašu požiadavku s týmito komplexnými typmi. SOAP im umožňuje byť odlišné.

Mal som niečo takéto:
...


FooBar

TagName nie je kľúč, ktorý chcete vložiť do svojej classmapy, musíte poznať názov ComplexType, na ktorý odkazuje tento TagName. Tieto informácie sú obsiahnuté v prostriedku WSDL.

paulovitorbal na gmail bodka com

Pri použití certifikátov použite v parametri "local_cert" obsah súboru, nie názov súboru.

New soapclient("http://localhost/index.php?wsdl ", array("local_cert"=>file_get_contents(./key.pem"),"passphrase"=>"heslo"));

V PHP môžete mať definované súkromné ​​vlastnosti v triedach, ktoré používate vo svojej triednej mape. Ak teda vo svojej triede vytvoríte súkromnú vlastnosť $foo a prvok SOAP má podradený prvok , obsah $foo bude nastavený na obsah . Týmto spôsobom môžete ovládať prístup k vlastnostiam vo svojich triedach.

(Poznámka: Toto nefunguje v HPHP Facebooku).

willem bodka stuursma at hyves bodka nl

Ak chcete použiť triedy v inom priestore názvov v mape tried, použite opačnú lomku v názve cieľovej triedy.

Príklad:
$classmap = array("result" => "MyNamespace\\Result" );
?>

Spätnú lomku musíte zadať dvakrát, pretože je to únikový znak v reťazcoch.

simonlang zavináč gmx bodka ch

Príklad mydlového klienta s HTTP autentifikáciou cez proxy:

nový SoapClient(
"service.wsdl",
pole(
// Veci na vývoj.
"stopa" => 1 ,
"výnimky" => pravda ,
"cache_wsdl" => WSDL_CACHE_NONE ,
"features" => SOAP_SINGLE_ELEMENT_ARRAYS ,

// Autorizačné údaje pre požiadavku SOAP.
"login" => "username" ,
"heslo" => "heslo" ,

// Adresa URL proxy.
"proxy_host" => "example.com" , // Nepridávajte sem schému (http alebo https). To nebude fungovať.
"proxy_port" => 44300,

// Autorizačné údaje pre server proxy.
"proxy_login" => NULL ,
"proxy_password" => NULL ,
);
?>
Poskytnutie URL k súboru WSDL na vzdialenom serveri (ktorý je tiež chránený HTTP autentifikáciou) nefungovalo.Stiahol som WSDL a uložil som ho na lokálny server.

Asaf Meller

Plne fungujúca konfigurácia php .net mydla:
poznámky
1. web.config na .net serveri musí fungovať s basichttp väzbou.
2. parametre do funkcií mydla musia byť odovzdané ako:
array("parm1_name"=>"parm1_value",
"parm2_name"=>"parm2_value"...)

header("Content-Type: text/plain");

Skúste (
$options = array(
"soap_version" => SOAP_1_1 ,
"výnimky" => pravda ,
"stopa" => 1 ,
"cache_wsdl" => WSDL_CACHE_NONE
);
$client = nový SoapClient ( "http://www.example.com/end_point.wsdl", $options);

) catch (Výnimka $e ) (
ozvena"

Chyba výnimky!

" ;
echo $e -> getMessage();
}

Echo "beží HelloWorld:" ;

Skúste (
$response = $klient -> HelloWorld();

}
chytiť (výnimka $e)
{
echo "Zachytená výnimka: " , $e -> getMessage (), "\n" ;
}

Print_r($response);
?>
veľa štastia!
Asaf.

faebu zavináč faebu bodka ch

Mám rovnaké problémy, keď sa pokúšam načítať súbor WDSL, ktorý je chránený základnou autentifikáciou http, pretože parametre login a password sa používajú iba pre požiadavku, ale nie pri čítaní súboru wdsl. Používam iba nasledujúce riešenie stiahnutím xml na nechránené miesto na mojom serveri. Upozorňujeme, že toto nepodporuje žiadny druh ukladania do vyrovnávacej pamäte.

trieda SoapAuthClient rozširuje SoapClient (
/**
* Keďže balík PHP SOAP nepodporuje základnú autentifikáciu
* táto trieda stiahne súbor WDSL pomocou balíka cURL a
* vytvorí lokálnu kópiu wdsl na vašom serveri.
*Uistite sa, že ste zadali nasledujúci dodatočný parameter v
* Pole $options:
* wdsl_local_copy => pravda
*/

Súkromné ​​$cache_dir = "/home/example/htdocs/cache/" ;
private $cache_url = "http://www.example.com/cache/";

Funkcia SoapAuthClient ($wdsl, $options) (
if (isset($options [ "wdsl_local_copy" ]) &&
$options [ "wdsl_local_copy" ] == true &&
isset($options [ "prihlásenie" ]) &&
isset($options [ "heslo" ])) (

$file = md5(uniqid()). ".xml" ;

If (($fp = fopen ($this -> cache_dir . $file , "w" )) == false ) (
hodiť novú výnimku ( "Nepodarilo sa vytvoriť lokálny súbor WDSL (". $this -> cache_dir . $file. ")");
}

$ch = curl_init();
$kredit = ($options["prihlásenie"]. ":" . $options["heslo" ]);
curl_setopt($ch, CURLOPT_URL, $wdsl);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt ($ch, CURLOPT_USERPWD, $kredit);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt ($ch, CURLOPT_FILE, $fp);
if (($xml = curl_exec ($ch )) === false ) (
//curl_close($ch);
fclose($fp);
unlink ($this -> cache_dir . $file );

Vyhoď novú výnimku(curl_error($ch));
}

Curl_close($ch);
fclose($fp);
$wdsl = $this -> cache_url . $súbor ;
}

Unset($options [ "wdsl_local_copy" ]);
unset($options [ "wdsl_force_local_copy" ]);

Echo $wdsl ;
rodič :: __construct ($wdsl, $options);

Unlink ($this -> cache_dir . $file );
}
}
?>

tatupheba na gmail bodka com

Ahojte ľudia!

Tip pre vývojárov:

Pri programovaní nejakého mydlového servera nastavte direktívu "soap.wsdl_cache_enabled" v súbore php.ini na 0:

Soap.wsdl_cache_enabled=0

V opačnom prípade sa zobrazí veľa podivných chýb, ktoré hovoria, že váš wsdl je nesprávny alebo chýba.

Ak to urobíte, ušetríte si veľa zbytočnej bolesti.

titan na phpdevshell dot org

Je potrebné poznamenať, že ak sa zobrazí chybové hlásenie: "Odkaz na objekt nie je nastavený na inštanciu objektu.". Môže to byť spôsobené niečím tak jednoduchým, ako je odovzdanie nesprávnych parametrov. Keď sa pozriete na tento XML:



reťazec
Dátum Čas
Dátum Čas

Váš kód by mal vyzerať asi takto:

skús (
$options = array(
"soap_version" => SOAP_1_2 ,
"výnimky" => pravda ,
"stopa" => 1 ,
"cache_wsdl" => WSDL_CACHE_NONE
);
$client = nový SoapClient ( "http://example.com/doc.asmx?WSDL", $options);
// Všimnite si, kde sú značky "Get" a "request" v XML
$results = $klient -> Získať (pole("request" =>array("CustomerId" => "1234" )));
) catch (Výnimka $e ) (
ozvena"

Chyba výnimky!

" ;
echo $e -> getMessage();
}

$results = $klient -> Získať (pole("request" =>array("CustomerId" => "842115" )));
?>

Ak váš súbor WSDL obsahuje parameter s typom base64Binary, nemali by ste používať base64_encode() pri odovzdávaní vašich mydlových varov. Keď vykonáte požiadavku, knižnica SOAP automaticky base64 zakóduje vaše údaje, takže inak ich budete kódovať dvakrát.

Úryvok WSDL:

$string = "data_you_want_to_send___like_xml_in_soap";
$soap_data = array(
"foo" => "bar" ,
//"obsah" => base64_encode($string) // nerobte to
"content" => $string //urobte to
);
$response = $klient -> Odoslať ($soap_data );
?>

marcovtwout zavináč hotmail bodka com

Keďže som v SOAP nový, chvíľu som hľadal, aby som zistil, prečo moja správa dostáva odpoveď v soapUI, ale nie s mojím php kódom. Špecifická služba, ktorú som riešil, dáva pri úspechu HTTP 202 Accepted (žiadna odpoveď), ale pri chybách vracia správu SOAP.

situácia:
Pri použití (overeného) pripojenia klienta a súboru WDSL volania SOAP s typom "Jednosmerný" nedávajú hlavičku odpovede, aj keď sa odpoveď očakáva.

Riešenie:
Pri volaní konštruktora klienta nastavte SOAP_WAIT_ONE_WAY_CALLS v $options["features"].

tim na tdinternet bodka com

Zdá sa, že PHP 5.2.11 nie je veľmi náročné na správnosť WSDL.

Iní klienti SOAP sa sťažovali na problémy so schémou a priestorom názvov, zatiaľ čo SoapClient PHP fungoval úplne dobre. Oprava týchto problémov pre ostatných klientov však zlomila PHP SoapClient do bodu, keď sa objekty odovzdávané metóde SOAP stávali prázdnymi poľami na strane servera.

Ponaučenie: niektoré prvky mali predponu xsd: a iné nie - úplne sa uistite, že váš WSDL je správny a konzistentný (používam vylepšený súbor WSDL_Gen.php).

james dot ellis na gmail bodka com

Mal som problémy so získavaním odpovedí zo servera Coldfusion SOAP bez zjavných problémov s použitým klientom SoapClient.

Nakoniec som zistil, že server akceptoval iba požiadavky SOAP 1.1 a nie 1.2. Nie ste si istí, či ide o celosystémové nastavenie Coldfusion, ale ak narazíte na rovnakú stenu, skúste nastaviť možnosť SoapClient "soap_version" na konštantu SOAP_1_1 (čo je predvolené nastavenie, ale moje bolo predvolené na 1.2, pretože klient bol opätovne používaný pre inú službu )

ajcartmell zavináč fonant bodka com

Zdá sa, že existuje problém so špecifikovaním prázdnych reťazcov pre voľby proxy_host a proxy_port v posledných verziách PHP (od verzie novšej ako 5.2.9 a rovnakej alebo staršej ako 5.2.11).

Zadanie prázdnych hodnôt reťazcov pre proxy_host a proxy_port spôsobuje chyby typu „hostiteľ sa nenašiel“: zadanie NULL alebo FALSE funguje dobre.

bhargav bodka khatana zavináč gmail bodka com

Trvalo mi dlhšie ako týždeň, kým som prišiel na to, ako implementovať hlavičky WSSE (Web Service Security) v natívnom PHP SOAP. Na túto tému nie je k dispozícii veľa zdrojov, preto som si myslel, že to sem pridáte v prospech komunity.

Krok 1: Vytvorte dve triedy na vytvorenie štruktúry pre hlavičky WSSE

trieda clsWSSEAuth(
súkromné ​​$Používateľské meno ;
súkromné ​​$Heslo ;
funkcia __construct ($username, $password) (
$this -> Username = $username ;
$this -> Heslo = $heslo ;
}
}

Trieda clsWSSEToken (
private $UsernameToken ;
funkcia __construct ($innerVal)(
$this -> UsernameToken = $innerVal ;
}
}
?>
Krok 2: Vytvorte premenné Soap pre používateľské meno a heslo

$username = 1111 ;
$heslo = 1111 ;

//U svojho poskytovateľa si overte, ktorý priestor názvov zabezpečenia používajú.
$strWSSENS = "http://schemas.xmlsoap.org/ws/2002/07/secext";

$objSoapVarUser = new SoapVar($username, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objSoapVarPass = new SoapVar($heslo, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
?>
Krok 3: Vytvorte objekt pre triedu overenia a odovzdajte mydlovú var

$objWSSEAuth = nový clsWSSEAuth ($objSoapVarUser , $objSoapVarPass );
?>
Krok 4: Vytvorte SoapVar z objektu triedy Auth

$objSoapVarWSSEAuth= new SoapVar ($objWSSEAuth , SOAP_ENC_OBJECT , NULL , $strWSSENS , "UsernameToken" , $strWSSENS );
?>
Krok 5: Vytvorte objekt pre triedu tokenov

$objWSSEToken = nový clsWSSEToken ($objSoapVarWSSEAuth);
?>
Krok 6: Vytvorte SoapVar z objektu triedy Token

$objSoapVarWSSEToken= new SoapVar ($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, "UsernameToken", $strWSSENS);
?>
Krok 7: Vytvorte SoapVar pre uzol „Zabezpečenie“.

$objSoapVarHeaderVal=new SoapVar ($objSoapVarWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, "Bezpečnosť", $strWSSENS);
?>
Krok 8: Vytvorte objekt hlavičky z bezpečnostného mydlového varu

$objSoapVarWSSEHeader= new SoapHeader ($strWSSENS , "Zabezpečenie" , $objSoapVarHeaderVal , true , "http://abce.com");

//Tretí parameter tu robí "mustUnderstand=1
//Štvrtý parameter generuje "actor="http://abce.com ""
?>
Krok 9: Vytvorte objekt Soap Client

$objClient = nový SoapClient ($WSDL, $arrOptions);
?>
Krok 10: Nastavte hlavičky pre objekt soapclient

$objClient -> __setSoapHeaders (pole($objSoapVarWSSEHeader ));
?>
Krok 11: Záverečné volanie metódy

$objResponse = $objClient -> __soapCall ($strMethod , $requestPayloadString );
?>

Peter v spoločnosti webacoustics dot com

Zistil som, že načítanie WSDL zlyhá pri použití základnej autentifikácie v mydlovom klientovi. Takže som implementoval nasledujúce riešenie pomocou wget. Uvedomujem si, že wget nemusí byť voľbou pre niektoré prostredia, v takom prípade by cURL bola ďalšia najjednoduchšia vec.

$wsdl = get_wsdl ( "https://example.com/mydlo/sluzba?wsdl");
$this -> client = new SoapClient ($wsdl , array("user" => "someuser" , "password" => "somepassword" ));

Súkromná funkcia get_wsdl ($url) (
globálne $g ;
$url = escapeshellarg($url);
$cache_file = "/tmp/soap.wsdl." . md5($url);

//získajte iba nový wsdl každú hodinu
if(! file_exists ($cache_file ) || filectime ($cache_file )< time () - 3600 ) {
$agent = escapeshellarg("--user-agent=($g["useragent"])");
mwexec("wget ​​​​--quiet --timeout=5 ( $agent ) --no-check-certifikát --output-document=( $cache_file ) ( $url ) ");
if(! file_exists ($cache_file )) (
throw new Exception("Nepodarilo sa načítať WSDL na ( $url )" );
}
}
vrátiť
$cache_file ;
}
?>

meltir zavináč meltir bodka com

Pre tých, ktorí bojujú s proxy servermi overenými NTLM, tu je riešenie, ktoré používam atm:

/**
* Potomok SoapClient s podporou ntlm proxy autentifikácie
*
* @autor Meltir
*
*/
trieda NTLM_SoapClient rozširuje SoapClient (

Verejná funkcia __construct ($wsdl, $options = array()) (
if (empty($options [ "proxy_login" ]) || empty($options [ "proxy_password" ])) hodí novú výnimku ( "Na overenie NTLM sa vyžaduje prihlasovacie meno a heslo!");
$this -> proxy_login = $options [ "proxy_login" ];
$this -> proxy_password = $options [ "proxy_password" ];
$this -> proxy_host = (prázdne($options [ "proxy_host" ]) ? "localhost": $options[ "proxy_host"]);
$this-> proxy_port= (prázdne($options[ "proxy_port"]) ? 8080 : $options[ "proxy_port"]);
rodič:: __konštruovať($wsdl, $options);
}

/**
* Zavolajte na url pomocou curl s ntlm auth
*
* @param reťazec $url
* @param string $data
* @reťazec návratu
* @vyhodí chybu SoapFault na chybu pripojenia curl
*/
chránená funkciacallCurl($url, $data) {
$rukoväť= curl_init();
curl_setopt($rukoväť, CURLOPT_HEADER, falošné);
curl_setopt($rukoväť, CURLOPT_URL, $url);
curl_setopt($rukoväť, CURLOPT_FAILONERROR, pravda);
curl_setopt($rukoväť, CURLOPT_HTTPHEADER,Pole("PHP SOAP-NTLM klient"));
curl_setopt($rukoväť, CURLOPT_RETURNTRANSFER, pravda);
curl_setopt($rukoväť, CURLOPT_POSTFIELDS, $data);
curl_setopt($rukoväť, CURLOPT_PROXYUSERPWD, $this-> proxy_login. ":" . $this-> proxy_password);
curl_setopt($rukoväť, CURLOPT_PROXY, $this-> proxy_host. ":" . $this-> proxy_port);
curl_setopt($rukoväť, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
$response= curl_exec($rukoväť);
ak (prázdne (
$response)) {
hodiť nový
SoapFault("CURL chyba: ". curl_error($rukoväť), curl_errno($rukoväť));
}
curl_close($rukoväť);
vrátiť
$response;
}

Verejná funkcia __doRequest($žiadosť, $location, $akcia, $verzia, $one_way= 0 ) {
vrátiť
$this-> callCurl($location, $žiadosť);
}

}
?>

Vyžaduje zvlnenie a dalo by sa predĺžiť, ale pre moje jednoduché potreby to funguje.

eric dot caron na gmail bodka com

Myšlienka, na ktorú poukázal jan at bestbytes, a diskutovaná v chybe č. 27777, jeden bežný zdroj "Parsing WSDL: Cann"t find " chyba je pri pokuse o prístup k WSDL, ktoré je chránené HTTP autentifikáciou. Zadanie prihlasovacieho mena/hesla v 2. parametri nefunguje vždy; takže ak narazíte na toto chybové hlásenie a pokúšate sa získať prístup k chránenému súboru WSDL, skúste zadať používateľské meno a heslo s prvým parametrom.

Anonymný

Musel som bojovať s dosť zvláštnym správaním, keď som sa neúspešne pokúšal konzumovať štandardné webové služby Parlay X. Našiel som však riešenie na môj problém.

Problém, ktorému som čelil, sa týkal chybnej neplatnej základnej autentifikačnej požiadavky HTTP odoslanej webovej službe. Aj keď som posielal správne poverenia, vyskytla sa chyba overenia. Ukázalo sa, že PHP posielalo HTTP požiadavky na iný koncový bod, ktorý nie je vystavený priamo cez webovú službu a tento koncový bod nevyžaduje autentifikáciu.

Mojím riešením tohto problému bolo použitie týchto jednoduchých riadkov v príklade použitia metódy sendSms Paraly-X.

Najprv vytvorte mydlového klienta bez akýchkoľvek možností autentifikácie HTTP:

$klient= novýSoapClient($wsdl_url);
?>

Vyššie uvedená požiadavka uloží súbor wsdl do vyrovnávacej pamäte v adresári /tmp. Ihneď po tejto konštrukcii vytvoríme ďalšieho mydlového klienta, tentoraz s možnosťami autentifikácie HTTP:

skús (
$klient= novýSoapClient($wsdl_url, pole("Prihlásiť sa"=> "griffin",
"heslo"=> "heslo"));
) chytiť (
Výnimka $e) {
printf("Chyba:sendSms: %s\n", $e-> __natiahnuť());
vrátiť
falošné;
}
?>

Teraz by to malo fungovať bez problémov. Bez druhého volania PHP zavolá sendSms bez poverení, čo má za následok neúspešný pokus z dôvodu chýbajúcich autentifikačných informácií. Zistil som, že tento postup je najjednoduchší.

Tento proces by sa mal vykonať vždy, keď vyprší platnosť wsdl uloženého vo vyrovnávacej pamäti, alebo jednoducho jeden môže predĺžiť dobu životnosti uloženého wsdl z php.ini

jon dot gilbert at net-entwicklung dot de

Všimnite si, že vytvorenie mydlového klienta pre neplatnú URL (testujete, čo sa stane, keď služba nie je dostupná, však?) zvyčajne vyvolá výnimku, ktorú možno zachytiť pomocou try..catch. Ak je však xdebug aktívny, dostanete fatálnu chybu, ktorú samozrejme nemožno zachytiť.

sloloem na gmail bodka com

Mal som problém s diskusiou o použití classmap, ktorý mi dlho trvalo, kým som na to prišiel. Predpokladal som, že typ WSDL, na ktorý sa dokumenty odvolávali, je názov prvku, ktorý sa vracia v SOAP, takže napr.

A bol som zvedavý, prečo mapovanie
"classmap"=>array("node"=>"MyNode")

Neurobil nič.
Je to preto, že v mojom WSDL som definoval uzol ako:

Triedna mapa, ktorú som potreboval, bola:
"classmap"=>array("nodeType"=>"MyNode")

Podarilo sa mi nájsť názvy typov pomocou SoapClient->__getTypes ()
Neskôr som si uvedomil, kde by som mohol hľadať vo WSDL názov typu, ktorý som potreboval.

Neviem, či som vynechal niečo bolestne zrejmé, ale možno to môže objasniť niektoré dokumenty.

Jon

Mali sme nejaké problémy s pripojením SoapClient k externému serveru cez Microsoft ISA (v súčasnosti v.2006, ale to sa môže týkať aj iných verzií). Dodávame proxy_host, proxy_port, proxy_login a proxy_password, ale server ISA hlási prihlásenie vo svojom prihlási ako „anonymný“.

Náš správca systému sa domnieva, že je to spôsobené tým, že PHP neposkytuje informácie NTLN (bezpečnostný protokol Windows) v správnom formáte (a či by malo fungovať s proprietárnymi proxy servermi je samozrejme iná debata). Skúšali sme "username", "DOMAIN\username" bez efektu. Riešením je pridať výnimku na ISA server pre cieľový názov hostiteľa/IP; potom je možné zadať hodnotu null pre proxy_login a proxy_password a pripojenie by malo fungovať podľa očakávania.

Trochu súvisiaca poznámka, ak máte problémy, uistite sa, že číslo portu je zadané ako celé číslo. Niektoré verzie PHP nebudú používať proxy s SoapClient, ak je číslo portu zadané ako reťazec.

jan zavináč bestbytes bodka de

Môžete získať wsdl, ak sa vyžaduje základné overenie:

$login = "bert";
$heslo= "berts heslo";

$klient= novýSoapClient(
"http://". urlencode($login) . ":" . urlencode($heslo) . "@www.server.com/path/to/wsdl",
pole(
"Prihlásiť sa"=> $login,
"heslo"=> $heslo
)
);

?>

info na nicksilvestro dot net

Pre každého, kto má problémy s ArrayOf_xsd_string a dostáva chybu podobnú „Pre typ poľa (http://www.w3.org/2001/XMLSchema)string nie je definovaný žiadny deserializátor“
Skúste použiť parameter „features“ nastavený na SOAP_USE_XSI_ARRAY_TYPE – tým sa zabezpečí, že sa použije správny deserializátor.

napr.
$klient= novýSoapClient("some.wsdl", pole("Vlastnosti"=> SOAP_USE_XSI_ARRAY_TYPE));
?>

ostreľovač

Hľadal som dobrý príklad a nenašiel som ho,
konečne som to niekde našiel (zabudol som kde), myslím, že to je toto
najlepším príkladom je žiadosť o mydlo s viacerými parametrami

$params->AWSAccessKeyId = AMAZON_API_KEY;
$params->Request->SearchIndex = "Knihy";
$params->Požiadavka->Kľúčové slová = "php5 oop";

$amazon = new SoapClient("http://webservices.amazon.com
/AWSECommerceService/AWSECommerceService.wsdl");
$vysledok = $amazon->itemSearch($params);

alex on reutone comma com

Na prepojenie PHP SOAP s MS SOAP (CRM/EXCHANGE/...) som vytvoril niekoľko tried pomocou vysvetlenia nižšie a na iných miestach.
www.reutone.com/heb/articles.php?instance_id=62&actions=show&id=521

naugtur na gmail bodka com

Výnimka SoapFault: Zdá sa, že nemáme žiadny dokument XML už bolo spomenuté, že nastane, keď váš server vypíše niečo predtým ... > tag.

Pre všetkým, ktorí s tým majú problémy, ažiadny prístup ku kódu servera:
Takto vytvoríte proxy, ktorý by čistil odpovedeprevy

php
/**
* Jednoduchá trieda prevzatá z poznámky Jamesa Ellisa
*/
triedaProxy_ClientpredlžujeSoapClient{
chránené
$cacheDocument= "" ;
verejná funkcia
__konštruovať($wsdl, $options) {
rodič:: __konštruovať($wsdl, $options);
}

/**
* SetCacheDocument() nastaví predtým uložený obsah dokumentu
*/
verejná funkciaSetCacheDocument($document) {
$this-> cacheDocument= $document;
}

/**
* __doRequest() prepíše štandardný SoapClient na spracovanie lokálnej požiadavky
*/
verejná funkcia__doRequest() {
vrátiť
$this-> cacheDocument;
}
}

//vložte tento kód do svojej funkcie alebo kdekoľvek. Máte nastavené všetky požadované premenné

$klient= novýSoapClient($wsdl_url, $settings_array);
$void= $klient-> $metóda($params); //zavolajte, aby ste dostali odpoveď zo servera

$response_string= $klient-> __getLastResponse();

//táto časť odstraňuje veci
$štart= strpos($response_string, ");
$koniec= strrpos($response_string, ">" );
$response_string= podstr($response_string, $štart, $koniec- $štart+ 1 );

//pripravte si proxy
$proxy= novýProxy_Client($wsdl_url, $settings_array);
//a vyplňte ho odpoveďou servera
$proxy-> SetCacheDocument($response_string);

$and_finally_the_result_is= $proxy-> $metóda($params);

print_r($and_finally_the_result_is); //to vám umožní vidieť, čo tam je

?>

$method je názov metódy, napr. $method="getVersion";
$params - typické parametre pre mydlovú metódu

Tipy pre používateľov:

    Ak poznáte súbor WSDL, môžete nastaviť rýchly odkaz na formuláre klienta pomocou
    http://www.?template=/clientform.html&fn=soapform
    &SoapTemplate=žiadne&SoapWSDL=Váš_WSDL_súbor
    alebo
    http://www..html?SoapWSDL=Váš_WSDL_Súbor

    Server ukladá súbory WSDL do vyrovnávacej pamäte pri bežných operáciách, aby sa zlepšil výkon. Ak vykonáte nejaké zmeny v súbore WSDL, vyberte Nie začiarkavacie políčko.

Tipy pre vývojárov:

    Použite<dokumentáciu> kedykoľvek je to možné vo vašom súbore WSDL poskytnúť pokyny. Zobrazí sa v klientskom formulári.

    Ak má prvok pevný počet hodnôt, použite typ enumerácie. Zobrazia sa ako rozbaľovacie polia.

Kľúčové vlastnosti:

    Podpora schém XML z roku 1999 aj 2001. Nástroj používa schému definovanú v súbore WSDL na vytváranie požiadaviek SOAP.

    Podporujte pole a rad štruktúr. Podporované sú iba jednorozmerné polia. Ľutujeme, žiadne riedke polia.

    Schopný serializovať zložité typy údajov a pole zložitých typov údajov, dokonca aj viacúrovňové vstavané štruktúry.

    Spracovanie ID/HREF v správach SOAP aj v definíciách schém.

    Podporujte SOAP sekciu 5/7 aj kódovanie dokumentu/doslova.

Technické detaily-- Dynamická väzba služieb SOAP

Väzba je zmluva medzi logikou klienta a logikou servera. V SOAP existujú dva typy väzieb: väzba objektu (alebo väzba SOAP) a väzba parametrov. Väčšina súprav nástrojov SOAP vykonáva statické väzby objektov generovaním proxy objektov na strane klienta. Problém je v tom, že na rozdiel od tradičného programovacieho modulu, kde sú objekty/rozhrania stabilné, webové služby podliehajú zmenám kedykoľvek bez upozornenia, pretože ich často vlastní/kontroluje tretia strana. Ďalší problém nastáva, keď sa zvýši počet webových služieb, ku ktorým sa dá pristupovať, vygenerovaný zdrojový kód sa môže rýchlo stať nočnou morou údržby. Nakoniec, keď sú webové služby, ku ktorým sa má pristupovať, neznáme, čo je častejšie ako pravdepodobné, skoré viazanie sa stáva nemožné alebo prinajmenšom zložité. Generovanie proxy objektu pre službu, ktorá sa má vybudovať v budúcnosti, je zaujímavým výskumným projektom.

Všeobecný klient SOAP demonštruje dynamické väzby (alebo väzby za chodu) služieb a parametrov SOAP. Objekt sa vygeneruje v čase vykonávania, keď je zadaný súbor WSDL, a hodnoty parametrov sú priradené k správe SOAP tesne pred doručením. Technika neskorej väzby (alebo oneskorenej väzby) by mohla výrazne znížiť náklady na údržbu, pretože na prístup k mnohým webovým službám možno použiť jedného klienta.

chyba: Obsah je chránený!!