Príklady mydla Php. Všetky kroky potrebné na pripojenie k webovej službe (príklad WSDL a príklad SOAP). Úvod do schémy XML

  • 03.11.2019

Pozadie:

Vytváram webovú stránku webových služieb, ktorá bude poskytovať mnoho typov jednoduchých služieb nad rámec SOAP a možno aj iných protokolov. Cieľom je zjednodušiť veci, ako sú konverzie, analýza RSS, kontrola spamu a mnoho ďalších druhov práce. Stránka bude zameraná predovšetkým na začínajúcich vývojárov.

Môj problém:

Nikdy som nevyvinul C # ani .NET. Pred niekoľkými rokmi som hackol niekoľko VB6, ale je to tak. Teraz ich potrebujem niekoľko príklady vykonávania volaní RPC cez SOAP v C #... Pokúsil som sa to nájsť na webe a v Stack Overflow, ale nenašiel som veľa zdrojov a netuším, ako zdroje zoradiť (ktoré sú staré? Ktoré sú nesprávne? atď.).

Vytvoril som jednoduchý príklad služby, ktorá sa v PHP volá takto:

getCurrentYear (); // Táto metóda vráti celé číslo nazývané "rok"?>

Teraz chcem túto metódu nazvať čo najjednoduchšou v C #. Všetky odkazy a príklady sú vysoko cenené. Kde mám začať? Aké triedy / moduly / čo môžem použiť?

Riešenie vôbec nemusí zahŕňať SOAP, ak existuje lepší komunikačný rámec (zadná strana je pre rozšíriteľnosť), ale všimnite si, že serverová strana je implementovaná v PHP na Unixe, takže proprietárne riešenia Microsoftu zo strany servera sa pýtajú.

Všimnite si, že to potrebujem, aby som mohol napísať dokumentáciu, ktorú môže J. Random Web Developer sledovať (aj keď sú na zdieľanom webhostingu). Takže si myslím, že najlepším prístupom by malo byť robiť to iba v kóde, ale aj iné spôsoby, ako to urobiť, sú samozrejme vítané.

6 odpovedí

Ako som pochopil, chcete volať svoju webovú službu z klientskej aplikácie C #. Už máte službu a publikovaný súbor WSDL (opravte ma, ak sa mýlim). Teraz najjednoduchším spôsobom je vytvoriť proxy triedy vo vašej aplikácii C # (tento proces sa nazýva pridanie odkazu na službu). Existujú dva hlavné spôsoby, ako to urobiť: .NET poskytuje služby ASP.NET, čo je starý spôsob SOA a WCF, ako navrhoval John, čo je najnovší rámec od MS a poskytuje mnoho protokolov vrátane open source a MS aplikácií.

Teraz dosť teórie a poďme na to krok za krokom.

Služba Service1Client = nová služba Service1Client ();

int rok = service.getCurrentYear ();

Dúfam, že to pomôže, ak narazíte na nejaký problém, dajte nám vedieť.

Urobil som dosť z toho, o čom hovoríte, a interoperabilita SOAP naprieč platformami má jedno základné pravidlo: NAJPRV ZMLUVTE. Neodvodzujte WSDL z vášho kódu a potom sa nepokúšajte zostaviť klienta na inej platforme. Čokoľvek väčšie ako funkcie ako „Hello World“ pravdepodobne nedokáže vygenerovať kód, nebude hovoriť za behu alebo (môj obľúbený) nedokáže správne odoslať alebo prijať všetky údaje bez toho, aby došlo k chybe.

WSDL je však ošemetná, frustrujúca vec a vyhýbam sa písaniu od začiatku, kedykoľvek je to možné. Tu je niekoľko pokynov pre spoľahlivo spolupracujúce služby (pomocou webových odkazov, WCF, Axis2 / Java, WS02, Ruby, Python atď.):

Ak to dokážete spustiť v prehliadači, potom niečo jednoduché, ako to funguje

Var webRequest = WebRequest.Create (@ "http://webservi.se/year/getCurrentYear"); using (var response = webRequest.GetResponse ()) (pomocou (var rd = new StreamReader (response.GetResponseStream ())) (var soapResult = rd.ReadToEnd ();))

Pozrite sa aj na NuSOAP. Ak ste teraz, toto je súprava nástrojov, ktorá vám umožňuje pripojiť sa z PHP k službe WCF.

Potrebujem sa pripojiť k jednej webovej službe a toto je všetko, čo mám:

    Príklad volania:

    Používateľské meno heslo

    Viem, že táto funkcia vracia reťazec;

Toto som doteraz urobil:

    Vytvoril odkaz na službu pridaním iba adresy WSDL špecifikovanej v odseku 1.

    Vytvorili ste inštanciu webovej služby a zavolali funkciu so všetkými požadovanými parametrami, ale nie s používateľom a heslom pre titul.

Ako môžem postupovať? Vopred ďakujem.

1 odpoveď

Toto môže byť dobré miesto, kde začať, ak potrebujete pridať svoje poverenia; Myslím, že možno budeš musieť, keďže si ich nejako získal. Časť, do ktorej pridávate svoje poverenia, je uvedená nižšie:

UsernameToken userToken = nový UsernameToken (používateľské meno, heslo, PasswordOption.SendHashed); Služba1 službaProxy = nová služba1 (); SoapContext requestContext = serviceProxy.RequestSoapContext; requestContext.Security.Tokens.Add (userToken);

  1. Pridajte svoje poverenia ich vložením do konkrétneho tokenu – ktorého typ patrí do priestoru názvov Microsoft.Web.Services2.Security.Tokens
  2. Vytvorte proxy pre svoju službu (vo vyššie uvedenom príklade serviceProxy)
  3. Získajte prístup k hlavičke svojej požiadavky prostredníctvom služby RequestSoapContext
  4. Pridajte token k žiadosti

Tiež si myslím, že by ste mohli preskočiť časť „? Wsdl“ adresy URL, pretože súvisí so špecifikáciou webovej služby. Keď to urobíte, môžete skúsiť zavolať funkciu a zistiť, ako to celé funguje: ak by funkcia mala niečo vrátiť, skontrolujte, čo ste očakávali.

Ahojte všetci!
Náhodou som sa v poslednej dobe začal venovať vývoju webových služieb. Ale dnes téma nie je o mne, ale o tom, ako môžeme napísať našu XML webovú službu založenú na protokole SOAP 1.2.

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

  • napíšte svoju vlastnú implementáciu webovej aplikácie na strane servera;
  • napísať vlastnú implementáciu webovej aplikácie na strane klienta;
  • napíšte svoj vlastný popis webovej služby (WSDL);
  • odosielať klientskymi poliami rovnaký typ údajov na server.

Ako ste možno uhádli, všetky kúzla budú vykonané pomocou PHP a vstavaných tried SoapClient a SoapServer. Služba na odosielanie sms bude fungovať ako králik.

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 avizované 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. Samotný proces zaraďovania správ pre ich ďalšieho poskytovateľa, ž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. Na túto tému navrhujem, aby som nebol dlho múdry a okamžite si odpovedal na hlavné otázky:

  • Aké je minimálne množstvo dát, ktoré je potrebné odoslať na server, aby bolo možné odoslať SMS správu účastníkovi?
  • Aké je minimálne množstvo údajov, ktoré je potrebné odoslať zo servera na uspokojenie potrieb klienta?

Niečo mi hovorí, že to vyžaduje odoslanie nasledovného:

  • aj číslo mobilného telefónu
  • SMS text.

V zásade tieto dve charakteristiky na odoslanie stačia, no hneď si predstavím prípad, keď vám SMS s narodeninovým pozdravom príde o 3. hodine ráno, prípadne 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 je voliteľný, ale môže sa nám veľmi hodiť, ak potrebujeme šéfovi rýchlo povedať, koľkým našim klientom sme „potešili“ našimi novinkami, a nakresliť aj pekné štatistiky o tomto skóre.

A predsa som na niečo zabudol! Ak sa zamyslíme trochu viac, potom stojí za zmienku, že klient môže naraz poslať na server jednu SMS správu a niekoľko z nich. Inými slovami, jeden dátový paket môže obsahovať od jednej až po nekonečné množstvo správ.

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

  • Telefónne číslo,
  • SMS text,
  • čas odoslania SMS správy účastníkovi,
  • typ správy.

Odpovedali sme na prvú otázku, teraz je potrebné odpovedať na druhú otázku. A možno si dovolím malý hack. Zo servera teda budeme posielať iba boolovské dáta, ktorých hodnota má nasledujúci význam:

  • TRUE - paket úspešne dorazil na server, bol overený a zaradený do fronty 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 tomu najzaujímavejšiemu - poďme zistiť, aké zvláštne zviera je toto MYDLO!

2 S čím je SOAP?

Vo všeobecnosti som pôvodne neplánoval písať nič o tom, čo je SOAP, a chcel som sa obmedziť na odkazy na stránku w3.org s potrebnými špecifikáciami, ako aj na odkazy na Wikipédiu. Ale na samom konci som sa rozhodol napísať krátku referenciu o tomto protokole.

A svoj príbeh začnem tým, že tento protokol výmeny dát patrí do podmnožiny protokolov založených na takzvanej paradigme RPC (Remote Procedure Call), ktorej opakom je REST (Representational State Transfer). Viac si o tom môžete prečítať na Wikipédii, odkazy na články sa nachádzajú na samom konci témy. Z týchto článkov musíme pochopiť nasledovné: „Prístup RPC vám umožňuje využívať malé množstvo sieťových prostriedkov 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 môže viesť k veľkému počtu individuálnych zdrojov." To znamená, že vo vzťahu k nám to znamená, že v prípade prístupu RPC bude vždy jeden vstup (odkaz) na službu na stránke a aký postup zavolať na spracovanie prichádzajúcich údajov, ktoré odovzdávame spolu s údajmi , pričom pri REST prístupe má na našej stránke veľa vstupov (odkazov), z ktorých každý akceptuje a spracováva len určité údaje. Ak niekto čítajúci vie, ako ešte jednoduchšie vysvetliť rozdiel v týchto prístupoch, potom 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 okamžite sa v našom arzenáli dostane všetka sila hromady technológií založených na tomto značkovacom jazyku do nášho arzenálu, konkrétne XML-Schema - jazyk na popis štruktúry dokumentu XML (vďaka Wikipédii!), ktorý umožňuje automatickú validáciu údajov prichádzajúce na server 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, odtiaľ sa tiež dozviete, že ho možno použiť nad akýmkoľvek protokolom aplikačnej vrstvy, a to nielen v tandeme s HTTP (žiaľ, v tejto téme budeme brať do úvahy iba SOAP cez HTTP). A viete čo sa mi na tom všetkom páči najviac? Ak neexistujú žiadne dohady, potom vám poradím - MYDLO! ... Každopádne, neboli žiadne dohady? ... Určite ste čítali článok na Wikipédii? ... Vo všeobecnosti vás už nebudem 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šie veci na tomto riadku sú uvedené kurzívou! Neviem ake zavery si z toho vsetkeho vyvodil, ale ja vidim nasledujuce - kedze tento protokol sa neda nazvat "jednoduchym" (a zjavne s tym suhlasim ani vo w3), od verzie 1.2 sa to prestalo nejako dešifrovat ! A stalo sa známe ako SOAP, len obdobie SOAP.

Dobre, ospravedlňujem sa, preniesli to trochu nabok. Ako som už písal, ako transport sa používa XML a balíky, ktoré prechádzajú medzi klientom a serverom, sa nazývajú SOAP obálky. Ak vezmeme do úvahy všeobecnú štruktúru obálky, bude sa vám zdať veľmi známa, pretože pripomína označenie stránky HTML. Má hlavnú časť - Obálka ktorá zahŕňa sekcie Hlavička a Telo alebo Chyba... V Teloúdaje sa prenášajú a je to povinná časť obálky, pričom Hlavička je voliteľná. V Hlavička môže byť prenášaná autorizácia 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.

Týmto sa končí môj prehľadný príbeh o protokole SOAP (samotnými obálkami a ich štruktúrou sa budeme podrobnejšie zaoberať, keď sa náš klient a server konečne naučia, ako ich navzájom spúšťať) a začína sa 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 odstrašuje od samotného pokusu prevziať a implementovať naše API na tento protokol. Výsledkom je, že zvyčajne znovu vynájdeme naše koleso s JSON na prepravu. Č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 z tejto definície nerozumiete celému posvätnému významu tejto technológie, potom sa ju pokúsim opísať vlastnými slovami!

WSDL je navrhnutý tak, aby naši klienti mohli normálne komunikovať so serverom. Na tento účel sú v súbore s príponou „* .wsdl“ popísané 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,
  • Aké údaje patria k akým postupom webovej služby,
  • Aké postupy obsahuje webová služba,
  • Ako by mal klient nazvať postupy webovej služby,
  • Na akú adresu sa majú odosielať hovory klienta.

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. Potrebujete len poznať umiestnenie jeho súboru WSDL! Čoskoro sa dozvieme, že MYDLO nie je také hrozné, ako sa maľuje (c) ruské príslovia.

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 spôsob interakcie medzi klientom a serverom a ako prenos sa naň používa značkovací jazyk XML, v tejto časti trochu pochopíme, ako sa údaje automaticky overujú pomocou schém XML.

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

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

Niečo veľmi jednoduché, čo nemá vo vnútri rozšírenia. Ich antipódom sú zložité komplexné typy. Najjednoduchším príkladom zložitého typu, ktorý si môže každý predstaviť, sú predmety. Napríklad kniha. Kniha obsahuje vlastnosti: autora, titul, cena, ISBN číslo atď. A tieto vlastnosti môžu byť jednoduché aj zložité. A úlohou XML schémy je opísať ju.

Navrhujem, aby ste nešli ďaleko a napísali 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

Naša schéma komplexného typu 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 množiny prvkov" telefón»Napíšte reťazec, « text»Napíšte reťazec, « dátum»Napíšte Dátum Čas, « typu»Napíšte 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 viac-menej jasné, takže sa im už nebudeme venovať a okamžite prejdeme na skladateľský prvok" sekvencie". Keď použijeme prvok skladateľ " sekvencie»Informujeme, že prvky v ňom obsiahnuté sa musia vždy nachádzať v poradí uvedenom v diagrame a tiež sú povinné všetky. Ale nezúfajte! V schémach XML sú ďalšie dva prvky skladateľa: „ výber" a " všetky". skladateľ" výber"Informuje, že by mal byť v ňom uvedený jeden z prvkov a skladateľ" všetky"- akákoľvek kombinácia uvedených prvkov.

Ako si pamätáte, v prvej časti témy sme sa zhodli, že v pakete možno prenášať od jednej po nekonečné SMS správy. 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

Schéma 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é kvalifikačné atribúty" minOccurs" a " maxOccurs". Ako ste mohli uhádnuť z názvu, prvý ( minOccurs) označuje, že táto postupnosť musí obsahovať aspoň jeden prvok typu „ telefón», « text», « dátum" a " typu“, Zatiaľ čo ďalšie ( maxOccurs) atribút nám deklaruje, že v našej sekvencii je najviac jeden takýto prvok. Výsledkom je, že keď píšeme naše schémy pre akékoľvek údaje, máme najširší výber pri ich prispôsobení!

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 Písanie vlastného WSDL

Pamätáte si, že WSDL je naša webová služba? Dúfam, že si pamätáš! Keď ho napíšeme, bude na ňom plávať naša malá webová služba. Preto navrhujem nepodvádzať.

Vo všeobecnosti, aby všetko fungovalo správne, musíme klientovi preniesť súbor WSDL so správnym typom MIME. Aby ste to dosiahli, 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

V praxi však zvyčajne posielam hlavičku HTTP „ text / xml»:

Hlavička ("Typ obsahu: text / xml; znaková sada = 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á a po napísaní ho môžete neustále kopírovať z jednej webovej služby do druhej!

Keďže WSDL je XML, hneď v prvom riadku o ňom musíte písať priamo. Koreňový prvok súboru musí mať vždy názov " 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ý bod.

Tu je napísané, že máme službu s názvom - " Služba SMS". V podstate môžete zmeniť všetky názvy v súbore WSDL na čokoľvek, čo chcete. nehrajú absolútne žiadnu rolu.

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

Potom, čo sme definovali webovú službu a určili pre ňu vstupný bod, musíme s ňou spojiť podporované procedúry:

Na to je uvedené, aké operácie a v akej forme sa budú nazývať. Tie. pre prístav" SmsServicePort"Väzba je definovaná pod názvom" SmsServiceBinding", ktorý má typ hovoru" rpc„A ako prenosový protokol (transport) sa používa HTTP. 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 špecifikované, že sa použijú štandardné SOAP obálky.

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) bude teda pomenovaná „ 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 na vstup má prísť obálka, ktorej štruktúra zodpovedá typu údajov " Žiadosť". Potom server vráti obálku obsahujúcu typ údajov - " odpoveď».

Teraz musíme urobiť najmenšiu vec - pridať popis týchto typov do nášho súboru WSDL! A ako si myslíte, že WSDL popisuje prichádzajúce a odchádzajúce údaje? 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 tohto 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

Skôr som napísal, že na vytvorenie servera SOAP v PHP použijeme vstavanú triedu SoapServer. Aby všetky ďalšie akcie prebehli rovnako ako moje, budete musieť trochu upraviť svoje PHP. Presnejšie povedané, musíte sa uistiť, že máte nainštalované rozšírenie „php-soap“. Ako ho umiestniť 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 pri funkcii „ini_set“. Pretože tam sa určí, ktoré HTTP hlavičky budeme posielať zo servera klientovi a je nakonfigurované prostredie. 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ý server SOAP má iba tri riadky! V prvom riadku vytvoríme novú inštanciu objektu SoapServer a odošleme ju konštruktorovi na adresu nášho popisu webovej služby WSDL. 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... V 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 sekcie, 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 nám výsledný server mal úplne vyhovovať, pretože môžeme zaznamenať prichádzajúce obálky a potom pokojne analyzovať prichádzajúce údaje. Aby sme mohli niečo prijímať 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 pomenujeme ho „ klient.php“, A vo vnútri píš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, pole (" 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 vstupujú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.

Potom, čo sme definovali objekty, musíme vytvoriť objekt ( $ req), ktorý odošleme na server. Potom sú tu pre nás dve najcennejšie línie! Náš SOAP klient! Verte tomu alebo nie, ale to stačí na to, aby sa správy od klienta začali hrnúť na náš server, ako aj na to, aby ich náš server úspešne prijal a spracoval! V prvom z nich vytvoríme inštanciu triedy SoapClient a jeho konštruktorovi odovzdáme adresu umiestnenia súboru WSDL a v parametroch explicitne uvedieme, že budeme pracovať pomocou 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:

Objekt (stdClass) verejný "stav" => boolean true

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

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

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

Toto je obálka. Teraz viete, ako to vyzerá! Ale sotva bude pre nás zaujímavé neustále ho obdivovať, tak poďme deserializovať objekt zo súboru denníka a uvidíme, či je s nami všetko v poriadku:

Object (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "phone" => string "79871234567" (dĺžka = 11) public "text" => string "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)

Ako vidíte, objekt bol deserializovaný správne, k čomu nám všetkým chcem zablahoželať! Ďalej nás čaká niečo zaujímavejšie! Totiž - klientom pošleme na server nie jednu sms správu, ale celú kopu (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ť:

// vytvorte objekt na odoslanie na server $ req = new Request (); $ req-> messageList = new MessageList (); $ msg1 = nová správa (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testovacia správa 1"; $ msg1-> dátum = "2013-07-21T15: 00: 00.26"; $ msg1-> typ = 15; $ msg2 = nová správa (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testovacia správa 2"; $ msg2-> dátum = "2014-08-22T16: 01: 10"; $ msg2-> typ = 16; $ msg3 = nová správa (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testovacia správa 3"; $ msg3-> dátum = "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 nasledujúci paket prišiel od klienta:

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 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 práve sme sa dozvedeli, že aký predmet odišiel z klienta, potom v úplne rovnakej podobe prišiel na náš server vo forme obálky. Pravda, sms správy neboli serializované do XML tak, ako sme potrebovali – museli byť zabalené do prvkov správu, nie v Štruktúra... Teraz sa pozrime, v akej forme takýto objekt prichádza do metódy poslaťSms:

Object (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "Struct" => 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 " zadajte "=> 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" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "type" => reťazec "16" (dĺžka = 2) 2 => objekt (stdClass) public "telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný" 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? Jedine, ž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?" Ale navrhujem, aby sme nezúfali a pokúsili sa obsadiť naše pole typu 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: 26.00 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" => objekt (stdClass) public "message" => objekt (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 " zadajte "=> 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" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "type" => reťazec "16" (dĺžka = 2) 2 => objekt (stdClass) public "telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný" 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, potom "zo zmeny miesta pojmov - súčet sa nemení" (c). Čo PODVODNÝ, čo Štruktúra- cieľ sa nám zatiaľ nepodarilo dosiahnuť! A aby sme to dosiahli, musíme sa postarať o to, aby sa namiesto týchto nezrozumiteľných mien zobrazoval náš rodák správu... Ako to však dosiahnuť, autor zatiaľ nevie. Preto jediné, čo môžeme urobiť, je zbaviť sa nadbytočnej nádoby. Inými slovami, teraz to urobíme tak, že namiesto toho správu sa stal PODVODNÝ! Ak to chcete urobiť, zmeňte objekt takto:

// vytvorte objekt na odoslanie na server $ req = new Request (); $ msg1 = nová správa (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testovacia správa 1"; $ msg1-> dátum = "2013-07-21T15: 00: 00.26"; $ msg1-> typ = 15; $ msg2 = nová správa (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testovacia správa 2"; $ msg2-> dátum = "2014-08-22T16: 01: 10"; $ msg2-> typ = 16; $ msg3 = nová správa (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testovacia správa 3"; $ msg3-> dátum = "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 sa vyberie správny názov? Ak to chcete urobiť, pozrime sa na prijatú obálku:

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 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! Vstúpte poslaťSms objekt v tomto prípade bude vyzerať takto:

Object (stdClass) public "messageList" => objekt (stdClass) public "BOGUS" => pole (veľkosť = 3) 0 => objekt (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) verejný" typ "=> reťazec" 16 "(dĺžka = 2) 2 => objekt (štandardná trieda) verejný" telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný "text" => reťazec "Testovacia správa 3" (dĺžka = 37) public "dátum" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "typ" => reťazec " 17" (dĺžka = 2)

Ako sa hovorí - "Takmer"! Na túto (trochu smutnú) poznámku navrhujem postupne zaokrúhliť a vyvodiť pre seba nejaké závery.

8 Záver

Konečne sme sa sem dostali! Definujme, čo teraz môžete urobiť:

  • môžete napísať požadovaný súbor WSDL pre vašu webovú službu;
  • môžete bez problémov napísať vlastného klienta, ktorý dokáže komunikovať so serverom pomocou protokolu 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 objektov rovnakého typu na server (s určitými obmedzeniami).

V priebehu nášho malého výskumu sme tiež urobili niekoľko objavov:

  • natívna trieda SoapClient nemôže správne serializovať dátové štruktúry rovnakého typu v XML;
  • pri serializácii poľa do XML sa vytvorí ďalší prvok s názvom Štruktúra;
  • pri serializácii objektu do XML sa vytvorí ďalší prvok s názvom PODVODNÝ;
  • PODVODNÝ menšie zlo ako Štruktúra 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 údaje obálky s našou schémou XML (možno iné servery nie).

klobúky 23. júla 2013 o 13:09

Písanie aplikácie SOAP klient-server v PHP

  • PHP
  • Návod

Ahojte všetci!
Náhodou som sa v poslednej dobe začal venovať vývoju webových služieb. Ale dnes téma nie je o mne, ale o tom, ako môžeme napísať našu XML webovú službu založenú na protokole SOAP 1.2.

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

  • napíšte svoju vlastnú implementáciu webovej aplikácie na strane servera;
  • napísať vlastnú implementáciu webovej aplikácie na strane klienta;
  • napíšte svoj vlastný popis webovej služby (WSDL);
  • odosielať klientskymi poliami rovnaký typ údajov na server.
Ako ste možno uhádli, všetky kúzla budú vykonané pomocou PHP a vstavaných tried SoapClient a SoapServer. Služba na odosielanie sms bude fungovať ako králik.

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 avizované 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. Samotný proces radenia správ na ich ďalšie odosielanie 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. Na túto tému navrhujem, aby som nebol dlho múdry a okamžite si odpovedal na hlavné otázky:
  • Aké je minimálne množstvo dát, ktoré je potrebné odoslať na server, aby bolo možné odoslať SMS správu účastníkovi?
  • Aké je minimálne množstvo údajov, ktoré je potrebné odoslať zo servera na uspokojenie potrieb klienta?
Niečo mi hovorí, že to vyžaduje odoslanie nasledovného:
  • aj číslo mobilného telefónu
  • SMS text.
V zásade tieto dve charakteristiky na odoslanie stačia, no hneď si predstavím prípad, keď vám SMS s narodeninovým pozdravom príde o 3. hodine ráno, prípadne 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 je voliteľný, ale môže sa nám veľmi hodiť, ak potrebujeme šéfovi rýchlo povedať, koľkým našim klientom sme „potešili“ našimi novinkami, a nakresliť aj pekné štatistiky o tomto skóre.

A predsa som na niečo zabudol! Ak sa zamyslíme trochu viac, potom stojí za zmienku, že klient môže naraz poslať na server jednu SMS správu a niekoľko z nich. Inými slovami, jeden dátový paket môže obsahovať od jednej až po nekonečné množstvo správ.

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

  • Telefónne číslo,
  • SMS text,
  • čas odoslania SMS správy účastníkovi,
  • typ správy.

Odpovedali sme na prvú otázku, teraz je potrebné odpovedať na druhú otázku. A možno si dovolím malý hack. Zo servera teda budeme posielať iba boolovské dáta, ktorých hodnota má nasledujúci význam:

  • TRUE - paket úspešne dorazil na server, bol overený a zaradený do fronty 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 tomu najzaujímavejšiemu - poďme zistiť, aké zvláštne zviera je toto MYDLO!

2 S čím je SOAP?

Vo všeobecnosti som pôvodne neplánoval písať nič o tom, čo je SOAP, a chcel som sa obmedziť na odkazy na stránku w3.org s potrebnými špecifikáciami, ako aj na odkazy na Wikipédiu. Ale na samom konci som sa rozhodol napísať krátku referenciu o tomto protokole.

A svoj príbeh začnem tým, že tento protokol výmeny dát patrí do podmnožiny protokolov založených na takzvanej paradigme RPC (Remote Procedure Call), ktorej opakom je REST (Representational State Transfer). Viac si o tom môžete prečítať na Wikipédii, odkazy na články sa nachádzajú na samom konci témy. Z týchto článkov musíme pochopiť nasledovné: „Prístup RPC vám umožňuje využívať malé množstvo sieťových prostriedkov 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 môže viesť k veľkému počtu individuálnych zdrojov." To znamená, že vo vzťahu k nám to znamená, že v prípade prístupu RPC na stránke 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, zatiaľ čo s prístupom REST má naša stránka veľa vstupov (odkazov), z ktorých každý prijíma a spracováva len určité údaje. Ak niekto čítajúci vie, ako ešte jednoduchšie vysvetliť rozdiel v týchto prístupoch, potom 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 okamžite sa v našom arzenáli dostane všetka sila hromady technológií založených na tomto značkovacom jazyku do nášho arzenálu, konkrétne XML-Schema - jazyk na popis štruktúry dokumentu XML (vďaka Wikipédii!), ktorý umožňuje automatickú validáciu údajov prichádzajúce na server 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, odtiaľ sa tiež dozviete, že ho možno použiť nad akýmkoľvek protokolom aplikačnej vrstvy, a to nielen v tandeme s HTTP (žiaľ, v tejto téme budeme brať do úvahy iba SOAP cez HTTP). A viete čo sa mi na tom všetkom páči najviac? Ak neexistujú žiadne dohady, potom vám poradím - MYDLO! ... Každopádne, neboli žiadne dohady? ... Určite ste čítali článok na Wikipédii? ... Vo všeobecnosti vás už nebudem 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šie veci na tomto riadku sú uvedené kurzívou! Neviem ake zavery si z toho vsetkeho vyvodil, ale ja vidim nasledujuce - kedze tento protokol sa neda nazvat "jednoduchym" (a zjavne s tym suhlasim ani vo w3), od verzie 1.2 sa to prestalo nejako dešifrovat ! A stalo sa známe ako SOAP, len obdobie SOAP.

Dobre, ospravedlňujem sa, šmýkalo sa to trochu nabok. Ako som už písal, ako transport sa používa XML a balíky, ktoré prechádzajú medzi klientom a serverom, sa nazývajú SOAP obálky. Ak vezmeme do úvahy všeobecnú štruktúru obálky, bude sa vám zdať veľmi známa, pretože pripomína štruktúru HTML stránky. Má hlavnú časť - Obálka ktorá zahŕňa sekcie Hlavička a Telo alebo Chyba... V Teloúdaje sa prenášajú a je to povinná časť obálky, pričom Hlavička je voliteľná. V Hlavička môže byť prenášaná autorizácia 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.

Týmto sa končí môj prehľadný príbeh o protokole SOAP (samotnými obálkami a ich štruktúrou sa budeme podrobnejšie zaoberať, keď sa náš klient a server konečne naučia, ako ich navzájom spúšťať) a začína sa 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 odstrašuje od samotného pokusu prevziať a implementovať naše API na tento protokol. Výsledkom je, že zvyčajne znovu vynájdeme naše koleso s JSON na prepravu. Č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 z tejto definície nerozumiete celému posvätnému významu tejto technológie, potom sa ju pokúsim opísať vlastnými slovami!

WSDL je navrhnutý tak, aby naši klienti mohli normálne komunikovať so serverom. Na tento účel sú v súbore s príponou „* .wsdl“ popísané 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,
  • Aké údaje patria k akým postupom webovej služby,
  • Aké postupy obsahuje webová služba,
  • Ako by mal klient nazvať postupy webovej služby,
  • Na akú adresu sa majú odosielať hovory klienta.
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. Potrebujete len poznať umiestnenie jeho súboru WSDL! Čoskoro sa dozvieme, že MYDLO nie je také hrozné, ako sa maľuje (c) ruské príslovia.

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 spôsob interakcie medzi klientom a serverom a ako prenos sa naň používa značkovací jazyk XML, v tejto časti trochu pochopíme, ako sa údaje automaticky overujú pomocou schém XML.

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

  • linka,
  • číslo,
  • boolovská hodnota,
  • dátum.
Niečo veľmi jednoduché, čo nemá vo vnútri rozšírenia. Ich antipódom sú zložité komplexné typy. Najjednoduchším príkladom zložitého typu, ktorý si môže každý predstaviť, sú predmety. Napríklad kniha. Kniha obsahuje vlastnosti: autora, titul, cena, ISBN číslo atď. A tieto vlastnosti môžu byť jednoduché aj zložité. A úlohou XML schémy je opísať ju.

Navrhujem, aby ste nešli ďaleko a napísali 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
Naša schéma komplexného typu 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 množiny prvkov" telefón»Napíšte reťazec, « text»Napíšte reťazec, « dátum»Napíšte Dátum Čas, « typu»Napíšte 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 viac-menej jasné, takže sa im už nebudeme venovať a okamžite prejdeme na skladateľský prvok" sekvencie". Keď použijeme prvok skladateľ " sekvencie»Informujeme, že prvky v ňom obsiahnuté sa musia vždy nachádzať v poradí uvedenom v diagrame a tiež sú povinné všetky. Ale nezúfajte! V schémach XML sú ďalšie dva prvky skladateľa: „ výber" a " všetky". skladateľ" výber"Informuje, že by mal byť v ňom uvedený jeden z prvkov a skladateľ" všetky"- akákoľvek kombinácia uvedených prvkov.

Ako si pamätáte, v prvej časti témy sme sa zhodli, že v pakete možno prenášať od jednej po nekonečné SMS správy. 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
Schéma 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é kvalifikačné atribúty" minOccurs" a " maxOccurs". Ako ste mohli uhádnuť z názvu, prvý ( minOccurs) označuje, že táto postupnosť musí obsahovať aspoň jeden prvok typu „ telefón», « text», « dátum" a " typu“, Zatiaľ čo ďalšie ( maxOccurs) atribút nám deklaruje, že v našej sekvencii je najviac jeden takýto prvok. Výsledkom je, že keď píšeme naše schémy pre akékoľvek údaje, máme najširší výber pri ich prispôsobení!

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 Písanie vlastného WSDL

Pamätáte si, že WSDL je naša webová služba? Dúfam, že si pamätáš! Keď ho napíšeme, bude na ňom plávať naša malá webová služba. Preto navrhujem nepodvádzať.

Vo všeobecnosti, aby všetko fungovalo správne, musíme klientovi preniesť súbor WSDL so správnym typom MIME. Aby ste to dosiahli, 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
V praxi však zvyčajne posielam hlavičku HTTP „ text / xml»:

Hlavička ("Typ obsahu: text / xml; znaková sada = 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á a po napísaní ho môžete neustále kopírovať z jednej webovej služby do druhej!

Keďže WSDL je XML, hneď v prvom riadku o ňom musíte písať priamo. Koreňový prvok súboru musí mať vždy názov " 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ý bod.


Tu je napísané, že máme službu s názvom - " Služba SMS". V podstate môžete zmeniť všetky názvy v súbore WSDL na čokoľvek, čo chcete. nehrajú absolútne žiadnu rolu.

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

Potom, čo sme definovali webovú službu a určili pre ňu vstupný bod, musíme s ňou spojiť podporované procedúry:


Na to je uvedené, aké operácie a v akej forme sa budú nazývať. Tie. pre prístav" SmsServicePort"Väzba je definovaná pod názvom" SmsServiceBinding", ktorý má typ hovoru" rpc„A ako prenosový protokol (transport) sa používa HTTP. 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 špecifikované, že sa použijú štandardné SOAP obálky.

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) bude teda pomenovaná „ 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 na vstup má prísť obálka, ktorej štruktúra zodpovedá typu údajov " Žiadosť". Potom server vráti obálku obsahujúcu typ údajov - " odpoveď».

Teraz musíme urobiť najmenšiu vec - pridať popis týchto typov do nášho súboru WSDL! A ako si myslíte, že WSDL popisuje prichádzajúce a odchádzajúce údaje? 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 tohto 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

Skôr som napísal, že na vytvorenie servera SOAP v PHP použijeme vstavanú triedu SoapServer. Aby všetky ďalšie akcie prebehli rovnako ako moje, budete musieť trochu upraviť svoje PHP. Presnejšie povedané, musíte sa uistiť, že máte nainštalované rozšírenie „php-soap“. Ako ho umiestniť 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 pri funkcii „ini_set“. Pretože tam sa určí, ktoré HTTP hlavičky budeme posielať zo servera klientovi a je nakonfigurované prostredie. 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ý server SOAP má iba tri riadky! V prvom riadku vytvoríme novú inštanciu objektu SoapServer a odošleme ju konštruktorovi na adresu nášho popisu webovej služby WSDL. 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... V 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 sekcie, 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 nám výsledný server mal úplne vyhovovať, pretože môžeme zaznamenať prichádzajúce obálky a potom pokojne analyzovať prichádzajúce údaje. Aby sme mohli niečo prijímať 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 pomenujeme ho „ klient.php“, A vo vnútri píš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, pole (" 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 vstupujú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.

Potom, čo sme definovali objekty, musíme vytvoriť objekt ( $ req), ktorý odošleme na server. Potom sú tu pre nás dve najcennejšie línie! Náš SOAP klient! Verte tomu alebo nie, ale to stačí na to, aby sa správy od klienta začali hrnúť na náš server, ako aj na to, aby ich náš server úspešne prijal a spracoval! V prvom z nich vytvoríme inštanciu triedy SoapClient a jeho konštruktorovi odovzdáme adresu umiestnenia súboru WSDL a v parametroch explicitne uvedieme, že budeme pracovať pomocou 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:

Objekt (stdClass) verejný "stav" => boolean true
A to je skvelé, pretože teraz s istotou vieme, že náš server funguje a nielen funguje, ale môže klientovi vrátiť niektoré hodnoty!

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

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 15
Toto je obálka. Teraz viete, ako to vyzerá! Ale sotva bude pre nás zaujímavé neustále ho obdivovať, tak poďme deserializovať objekt z log súboru a uvidíme, či je s nami všetko v poriadku:

Object (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "phone" => string "79871234567" (dĺžka = 11) public "text" => string "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)
Ako vidíte, objekt bol deserializovaný správne, k čomu nám všetkým chcem zablahoželať! Ďalej nás čaká niečo zaujímavejšie! Totiž - klientom pošleme na server nie jednu sms správu, ale celú kopu (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ť:

// vytvorte objekt na odoslanie na server $ req = new Request (); $ req-> messageList = new MessageList (); $ msg1 = nová správa (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testovacia správa 1"; $ msg1-> dátum = "2013-07-21T15: 00: 00.26"; $ msg1-> typ = 15; $ msg2 = nová správa (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testovacia správa 2"; $ msg2-> dátum = "2014-08-22T16: 01: 10"; $ msg2-> typ = 16; $ msg3 = nová správa (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testovacia správa 3"; $ msg3-> dátum = "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 nasledujúci paket prišiel od klienta:

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 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 práve sme sa dozvedeli, že ktorý objekt opustil klienta, potom v úplne rovnakej podobe prišiel na náš server vo forme obálky. SMS správy však neboli serializované do XML tak, ako sme potrebovali – museli byť zabalené do prvkov správu, nie v Štruktúra... Teraz sa pozrime, v akej forme takýto objekt prichádza do metódy poslaťSms:

Object (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "Struct" => 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 " zadajte "=> 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" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "type" => reťazec "16" (dĺžka = 2) 2 => objekt (stdClass) public "telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný" 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? Jedine, ž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?" Ale navrhujem, aby sme nezúfali a pokúsili sa obsadiť naše pole typu 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: 26.00 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" => objekt (stdClass) public "message" => objekt (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 " zadajte "=> 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" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "type" => reťazec "16" (dĺžka = 2) 2 => objekt (stdClass) public "telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný" 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, potom "zo zmeny miesta pojmov - súčet sa nemení" (c). Čo PODVODNÝ, čo Štruktúra- cieľ sa nám zatiaľ nepodarilo dosiahnuť! A aby sme to dosiahli, musíme sa postarať o to, aby sa namiesto týchto nezrozumiteľných mien zobrazoval náš rodák správu... Ako to však dosiahnuť, autor zatiaľ nevie. Preto jediné, čo môžeme urobiť, je zbaviť sa nadbytočnej nádoby. Inými slovami, teraz to urobíme tak, že namiesto toho správu sa stal PODVODNÝ! Ak to chcete urobiť, zmeňte objekt takto:

// vytvorte objekt na odoslanie na server $ req = new Request (); $ msg1 = nová správa (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testovacia správa 1"; $ msg1-> dátum = "2013-07-21T15: 00: 00.26"; $ msg1-> typ = 15; $ msg2 = nová správa (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testovacia správa 2"; $ msg2-> dátum = "2014-08-22T16: 01: 10"; $ msg2-> typ = 16; $ msg3 = nová správa (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testovacia správa 3"; $ msg3-> dátum = "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 sa vyberie správny názov? Ak to chcete urobiť, pozrime sa na prijatú obálku:

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 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! Vstúpte poslaťSms objekt v tomto prípade bude vyzerať takto:

Object (stdClass) public "messageList" => objekt (stdClass) public "BOGUS" => pole (veľkosť = 3) 0 => objekt (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) verejný" typ "=> reťazec" 16 "(dĺžka = 2) 2 => objekt (štandardná trieda) verejný" telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný "text" => reťazec "Testovacia správa 3" (dĺžka = 37) public "dátum" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "typ" => reťazec " 17" (dĺžka = 2)
Ako sa hovorí - "Takmer"! Na túto (trochu smutnú) poznámku navrhujem postupne zaokrúhliť a vyvodiť pre seba nejaké závery.

8 Záver

Konečne sme sa sem dostali! Definujme, čo teraz môžete urobiť:
  • môžete napísať požadovaný súbor WSDL pre vašu webovú službu;
  • môžete bez problémov napísať vlastného klienta, ktorý dokáže komunikovať so serverom pomocou protokolu 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 objektov rovnakého typu na server (s určitými obmedzeniami).
V priebehu nášho malého výskumu sme tiež urobili niekoľko objavov:
  • natívna trieda SoapClient nemôže správne serializovať dátové štruktúry rovnakého typu v XML;
  • pri serializácii poľa do XML sa vytvorí ďalší prvok s názvom Štruktúra;
  • pri serializácii objektu do XML sa vytvorí ďalší prvok s názvom PODVODNÝ;
  • PODVODNÝ menšie zlo ako Štruktúra vďaka tomu, že obálka je kompaktnejšia (do XML hlavičky obálky sa nepridávajú žiadne ďalšie menné priestory);
  • žiaľ, trieda SoapServer automaticky neoveruje údaje obálky s našou schémou XML (možno iné servery nie).
  • Návod

Ahojte všetci!
Náhodou som sa v poslednej dobe začal venovať vývoju webových služieb. Ale dnes téma nie je o mne, ale o tom, ako môžeme napísať našu XML webovú službu založenú na protokole SOAP 1.2.

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

  • napíšte svoju vlastnú implementáciu webovej aplikácie na strane servera;
  • napísať vlastnú implementáciu webovej aplikácie na strane klienta;
  • napíšte svoj vlastný popis webovej služby (WSDL);
  • odosielať klientskymi poliami rovnaký typ údajov na server.
Ako ste možno uhádli, všetky kúzla budú vykonané pomocou PHP a vstavaných tried SoapClient a SoapServer. Služba na odosielanie sms bude fungovať ako králik.

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 avizované 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. Samotný proces radenia správ na ich ďalšie odosielanie 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. Na túto tému navrhujem, aby som nebol dlho múdry a okamžite si odpovedal na hlavné otázky:
  • Aké je minimálne množstvo dát, ktoré je potrebné odoslať na server, aby bolo možné odoslať SMS správu účastníkovi?
  • Aké je minimálne množstvo údajov, ktoré je potrebné odoslať zo servera na uspokojenie potrieb klienta?
Niečo mi hovorí, že to vyžaduje odoslanie nasledovného:
  • aj číslo mobilného telefónu
  • SMS text.
V zásade tieto dve charakteristiky na odoslanie stačia, no hneď si predstavím prípad, keď vám SMS s narodeninovým pozdravom príde o 3. hodine ráno, prípadne 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 je voliteľný, ale môže sa nám veľmi hodiť, ak potrebujeme šéfovi rýchlo povedať, koľkým našim klientom sme „potešili“ našimi novinkami, a nakresliť aj pekné štatistiky o tomto skóre.

A predsa som na niečo zabudol! Ak sa zamyslíme trochu viac, potom stojí za zmienku, že klient môže naraz poslať na server jednu SMS správu a niekoľko z nich. Inými slovami, jeden dátový paket môže obsahovať od jednej až po nekonečné množstvo správ.

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

  • Telefónne číslo,
  • SMS text,
  • čas odoslania SMS správy účastníkovi,
  • typ správy.

Odpovedali sme na prvú otázku, teraz je potrebné odpovedať na druhú otázku. A možno si dovolím malý hack. Zo servera teda budeme posielať iba boolovské dáta, ktorých hodnota má nasledujúci význam:

  • TRUE - paket úspešne dorazil na server, bol overený a zaradený do fronty 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 tomu najzaujímavejšiemu - poďme zistiť, aké zvláštne zviera je toto MYDLO!

2 S čím je SOAP?

Vo všeobecnosti som pôvodne neplánoval písať nič o tom, čo je SOAP, a chcel som sa obmedziť na odkazy na stránku w3.org s potrebnými špecifikáciami, ako aj na odkazy na Wikipédiu. Ale na samom konci som sa rozhodol napísať krátku referenciu o tomto protokole.

A svoj príbeh začnem tým, že tento protokol výmeny dát patrí do podmnožiny protokolov založených na takzvanej paradigme RPC (Remote Procedure Call), ktorej opakom je REST (Representational State Transfer). Viac si o tom môžete prečítať na Wikipédii, odkazy na články sa nachádzajú na samom konci témy. Z týchto článkov musíme pochopiť nasledovné: „Prístup RPC vám umožňuje využívať malé množstvo sieťových prostriedkov 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 môže viesť k veľkému počtu individuálnych zdrojov." To znamená, že vo vzťahu k nám to znamená, že v prípade prístupu RPC na stránke 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, zatiaľ čo s prístupom REST má naša stránka veľa vstupov (odkazov), z ktorých každý prijíma a spracováva len určité údaje. Ak niekto čítajúci vie, ako ešte jednoduchšie vysvetliť rozdiel v týchto prístupoch, potom 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 okamžite sa v našom arzenáli dostane všetka sila hromady technológií založených na tomto značkovacom jazyku do nášho arzenálu, konkrétne XML-Schema - jazyk na popis štruktúry dokumentu XML (vďaka Wikipédii!), ktorý umožňuje automatickú validáciu údajov prichádzajúce na server 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, odtiaľ sa tiež dozviete, že ho možno použiť nad akýmkoľvek protokolom aplikačnej vrstvy, a to nielen v tandeme s HTTP (žiaľ, v tejto téme budeme brať do úvahy iba SOAP cez HTTP). A viete čo sa mi na tom všetkom páči najviac? Ak neexistujú žiadne dohady, potom vám poradím - MYDLO! ... Každopádne, neboli žiadne dohady? ... Určite ste čítali článok na Wikipédii? ... Vo všeobecnosti vás už nebudem 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šie veci na tomto riadku sú uvedené kurzívou! Neviem ake zavery si z toho vsetkeho vyvodil, ale ja vidim nasledujuce - kedze tento protokol sa neda nazvat "jednoduchym" (a zjavne s tym suhlasim ani vo w3), od verzie 1.2 sa to prestalo nejako dešifrovat ! A stalo sa známe ako SOAP, len obdobie SOAP.

Dobre, ospravedlňujem sa, šmýkalo sa to trochu nabok. Ako som už písal, ako transport sa používa XML a balíky, ktoré prechádzajú medzi klientom a serverom, sa nazývajú SOAP obálky. Ak vezmeme do úvahy všeobecnú štruktúru obálky, bude sa vám zdať veľmi známa, pretože pripomína štruktúru HTML stránky. Má hlavnú časť - Obálka ktorá zahŕňa sekcie Hlavička a Telo alebo Chyba... V Teloúdaje sa prenášajú a je to povinná časť obálky, pričom Hlavička je voliteľná. V Hlavička môže byť prenášaná autorizácia 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.

Týmto sa končí môj prehľadný príbeh o protokole SOAP (samotnými obálkami a ich štruktúrou sa budeme podrobnejšie zaoberať, keď sa náš klient a server konečne naučia, ako ich navzájom spúšťať) a začína sa 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 odstrašuje od samotného pokusu prevziať a implementovať naše API na tento protokol. Výsledkom je, že zvyčajne znovu vynájdeme naše koleso s JSON na prepravu. Č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 z tejto definície nerozumiete celému posvätnému významu tejto technológie, potom sa ju pokúsim opísať vlastnými slovami!

WSDL je navrhnutý tak, aby naši klienti mohli normálne komunikovať so serverom. Na tento účel sú v súbore s príponou „* .wsdl“ popísané 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,
  • Aké údaje patria k akým postupom webovej služby,
  • Aké postupy obsahuje webová služba,
  • Ako by mal klient nazvať postupy webovej služby,
  • Na akú adresu sa majú odosielať hovory klienta.
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. Potrebujete len poznať umiestnenie jeho súboru WSDL! Čoskoro sa dozvieme, že MYDLO nie je také hrozné, ako sa maľuje (c) ruské príslovia.

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 spôsob interakcie medzi klientom a serverom a ako prenos sa naň používa značkovací jazyk XML, v tejto časti trochu pochopíme, ako sa údaje automaticky overujú pomocou schém XML.

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

  • linka,
  • číslo,
  • boolovská hodnota,
  • dátum.
Niečo veľmi jednoduché, čo nemá vo vnútri rozšírenia. Ich antipódom sú zložité komplexné typy. Najjednoduchším príkladom zložitého typu, ktorý si môže každý predstaviť, sú predmety. Napríklad kniha. Kniha obsahuje vlastnosti: autora, titul, cena, ISBN číslo atď. A tieto vlastnosti môžu byť jednoduché aj zložité. A úlohou XML schémy je opísať ju.

Navrhujem, aby ste nešli ďaleko a napísali 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
Naša schéma komplexného typu 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 množiny prvkov" telefón»Napíšte reťazec, « text»Napíšte reťazec, « dátum»Napíšte Dátum Čas, « typu»Napíšte 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 viac-menej jasné, takže sa im už nebudeme venovať a okamžite prejdeme na skladateľský prvok" sekvencie". Keď použijeme prvok skladateľ " sekvencie»Informujeme, že prvky v ňom obsiahnuté sa musia vždy nachádzať v poradí uvedenom v diagrame a tiež sú povinné všetky. Ale nezúfajte! V schémach XML sú ďalšie dva prvky skladateľa: „ výber" a " všetky". skladateľ" výber"Informuje, že by mal byť v ňom uvedený jeden z prvkov a skladateľ" všetky"- akákoľvek kombinácia uvedených prvkov.

Ako si pamätáte, v prvej časti témy sme sa zhodli, že v pakete možno prenášať od jednej po nekonečné SMS správy. 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
Schéma 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é kvalifikačné atribúty" minOccurs" a " maxOccurs". Ako ste mohli uhádnuť z názvu, prvý ( minOccurs) označuje, že táto postupnosť musí obsahovať aspoň jeden prvok typu „ telefón», « text», « dátum" a " typu“, Zatiaľ čo ďalšie ( maxOccurs) atribút nám deklaruje, že v našej sekvencii je najviac jeden takýto prvok. Výsledkom je, že keď píšeme naše schémy pre akékoľvek údaje, máme najširší výber pri ich prispôsobení!

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 Písanie vlastného WSDL

Pamätáte si, že WSDL je naša webová služba? Dúfam, že si pamätáš! Keď ho napíšeme, bude na ňom plávať naša malá webová služba. Preto navrhujem nepodvádzať.

Vo všeobecnosti, aby všetko fungovalo správne, musíme klientovi preniesť súbor WSDL so správnym typom MIME. Aby ste to dosiahli, 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
V praxi však zvyčajne posielam hlavičku HTTP „ text / xml»:

Hlavička ("Typ obsahu: text / xml; znaková sada = 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á a po napísaní ho môžete neustále kopírovať z jednej webovej služby do druhej!

Keďže WSDL je XML, hneď v prvom riadku o ňom musíte písať priamo. Koreňový prvok súboru musí mať vždy názov " 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ý bod.


Tu je napísané, že máme službu s názvom - " Služba SMS". V podstate môžete zmeniť všetky názvy v súbore WSDL na čokoľvek, čo chcete. nehrajú absolútne žiadnu rolu.

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

Potom, čo sme definovali webovú službu a určili pre ňu vstupný bod, musíme s ňou spojiť podporované procedúry:


Na to je uvedené, aké operácie a v akej forme sa budú nazývať. Tie. pre prístav" SmsServicePort"Väzba je definovaná pod názvom" SmsServiceBinding", ktorý má typ hovoru" rpc„A ako prenosový protokol (transport) sa používa HTTP. 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 špecifikované, že sa použijú štandardné SOAP obálky.

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) bude teda pomenovaná „ 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 na vstup má prísť obálka, ktorej štruktúra zodpovedá typu údajov " Žiadosť". Potom server vráti obálku obsahujúcu typ údajov - " odpoveď».

Teraz musíme urobiť najmenšiu vec - pridať popis týchto typov do nášho súboru WSDL! A ako si myslíte, že WSDL popisuje prichádzajúce a odchádzajúce údaje? 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 tohto 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

Skôr som napísal, že na vytvorenie servera SOAP v PHP použijeme vstavanú triedu SoapServer. Aby všetky ďalšie akcie prebehli rovnako ako moje, budete musieť trochu upraviť svoje PHP. Presnejšie povedané, musíte sa uistiť, že máte nainštalované rozšírenie „php-soap“. Ako ho umiestniť 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 pri funkcii „ini_set“. Pretože tam sa určí, ktoré HTTP hlavičky budeme posielať zo servera klientovi a je nakonfigurované prostredie. 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ý server SOAP má iba tri riadky! V prvom riadku vytvoríme novú inštanciu objektu SoapServer a odošleme ju konštruktorovi na adresu nášho popisu webovej služby WSDL. 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... V 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 sekcie, 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 nám výsledný server mal úplne vyhovovať, pretože môžeme zaznamenať prichádzajúce obálky a potom pokojne analyzovať prichádzajúce údaje. Aby sme mohli niečo prijímať 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 pomenujeme ho „ klient.php“, A vo vnútri píš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, pole (" 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 vstupujú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.

Potom, čo sme definovali objekty, musíme vytvoriť objekt ( $ req), ktorý odošleme na server. Potom sú tu pre nás dve najcennejšie línie! Náš SOAP klient! Verte tomu alebo nie, ale to stačí na to, aby sa správy od klienta začali hrnúť na náš server, ako aj na to, aby ich náš server úspešne prijal a spracoval! V prvom z nich vytvoríme inštanciu triedy SoapClient a jeho konštruktorovi odovzdáme adresu umiestnenia súboru WSDL a v parametroch explicitne uvedieme, že budeme pracovať pomocou 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:

Objekt (stdClass) verejný "stav" => boolean true
A to je skvelé, pretože teraz s istotou vieme, že náš server funguje a nielen funguje, ale môže klientovi vrátiť niektoré hodnoty!

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

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 15
Toto je obálka. Teraz viete, ako to vyzerá! Ale sotva bude pre nás zaujímavé neustále ho obdivovať, tak poďme deserializovať objekt z log súboru a uvidíme, či je s nami všetko v poriadku:

Object (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "phone" => string "79871234567" (dĺžka = 11) public "text" => string "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)
Ako vidíte, objekt bol deserializovaný správne, k čomu nám všetkým chcem zablahoželať! Ďalej nás čaká niečo zaujímavejšie! Totiž - klientom pošleme na server nie jednu sms správu, ale celú kopu (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ť:

// vytvorte objekt na odoslanie na server $ req = new Request (); $ req-> messageList = new MessageList (); $ msg1 = nová správa (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testovacia správa 1"; $ msg1-> dátum = "2013-07-21T15: 00: 00.26"; $ msg1-> typ = 15; $ msg2 = nová správa (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testovacia správa 2"; $ msg2-> dátum = "2014-08-22T16: 01: 10"; $ msg2-> typ = 16; $ msg3 = nová správa (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testovacia správa 3"; $ msg3-> dátum = "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 nasledujúci paket prišiel od klienta:

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 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 práve sme sa dozvedeli, že ktorý objekt opustil klienta, potom v úplne rovnakej podobe prišiel na náš server vo forme obálky. SMS správy však neboli serializované do XML tak, ako sme potrebovali – museli byť zabalené do prvkov správu, nie v Štruktúra... Teraz sa pozrime, v akej forme takýto objekt prichádza do metódy poslaťSms:

Object (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "Struct" => 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 " zadajte "=> 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" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "type" => reťazec "16" (dĺžka = 2) 2 => objekt (stdClass) public "telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný" 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? Jedine, ž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?" Ale navrhujem, aby sme nezúfali a pokúsili sa obsadiť naše pole typu 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: 26.00 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" => objekt (stdClass) public "message" => objekt (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 " zadajte "=> 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" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "type" => reťazec "16" (dĺžka = 2) 2 => objekt (stdClass) public "telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný" 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, potom "zo zmeny miesta pojmov - súčet sa nemení" (c). Čo PODVODNÝ, čo Štruktúra- cieľ sa nám zatiaľ nepodarilo dosiahnuť! A aby sme to dosiahli, musíme sa postarať o to, aby sa namiesto týchto nezrozumiteľných mien zobrazoval náš rodák správu... Ako to však dosiahnuť, autor zatiaľ nevie. Preto jediné, čo môžeme urobiť, je zbaviť sa nadbytočnej nádoby. Inými slovami, teraz to urobíme tak, že namiesto toho správu sa stal PODVODNÝ! Ak to chcete urobiť, zmeňte objekt takto:

// vytvorte objekt na odoslanie na server $ req = new Request (); $ msg1 = nová správa (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testovacia správa 1"; $ msg1-> dátum = "2013-07-21T15: 00: 00.26"; $ msg1-> typ = 15; $ msg2 = nová správa (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testovacia správa 2"; $ msg2-> dátum = "2014-08-22T16: 01: 10"; $ msg2-> typ = 16; $ msg3 = nová správa (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testovacia správa 3"; $ msg3-> dátum = "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 sa vyberie správny názov? Ak to chcete urobiť, pozrime sa na prijatú obálku:

79871234567 Testovacia správa 1 2013-07-21T15: 00: 26.00 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! Vstúpte poslaťSms objekt v tomto prípade bude vyzerať takto:

Object (stdClass) public "messageList" => objekt (stdClass) public "BOGUS" => pole (veľkosť = 3) 0 => objekt (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) verejný" typ "=> reťazec" 16 "(dĺžka = 2) 2 => objekt (štandardná trieda) verejný" telefón "=> reťazec" 79871234567 "(dĺžka = 11) verejný "text" => reťazec "Testovacia správa 3" (dĺžka = 37) public "dátum" => reťazec "2014-08-22T16: 01: 10" (dĺžka = 19) public "typ" => reťazec " 17" (dĺžka = 2)
Ako sa hovorí - "Takmer"! Na túto (trochu smutnú) poznámku navrhujem postupne zaokrúhliť a vyvodiť pre seba nejaké závery.

8 Záver

Konečne sme sa sem dostali! Definujme, čo teraz môžete urobiť:
  • môžete napísať požadovaný súbor WSDL pre vašu webovú službu;
  • môžete bez problémov napísať vlastného klienta, ktorý dokáže komunikovať so serverom pomocou protokolu 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 objektov rovnakého typu na server (s určitými obmedzeniami).
V priebehu nášho malého výskumu sme tiež urobili niekoľko objavov:
  • natívna trieda SoapClient nemôže správne serializovať dátové štruktúry rovnakého typu v XML;
  • pri serializácii poľa do XML sa vytvorí ďalší prvok s názvom Štruktúra;
  • pri serializácii objektu do XML sa vytvorí ďalší prvok s názvom PODVODNÝ;
  • PODVODNÝ menšie zlo ako Štruktúra vďaka tomu, že obálka je kompaktnejšia (do XML hlavičky obálky sa nepridávajú žiadne ďalšie menné priestory);
  • žiaľ, trieda SoapServer automaticky neoveruje údaje obálky s našou schémou XML (možno iné servery nie).