Exemple de clienți PHP soap. Scrierea unei aplicații SOAP client-server în PHP
Trebuie să mă conectez la un serviciu web și asta este tot ce am:
Exemplu de apel:
Știu că această funcție returnează un șir;
Iată ce am făcut până acum:
A creat o referință de serviciu, adăugând doar adresa WSDL specificată la pasul 1.
Am creat o instanță de serviciu web și am apelat funcția cu toți parametrii necesari, dar nu utilizatorul și parola pentru antet.
Cum ar trebui să continui? Mulţumesc anticipat.
1 raspuns
Acesta ar putea fi un loc bun pentru a începe dacă trebuie să vă adăugați acreditările; Cred că ar trebui să o faci din moment ce le-ai luat cumva. Partea în care vă adăugați acreditările este mai jos:
UsernameToken userToken = new UsernameToken (nume utilizator, parola, PasswordOption.SendHashed); Service1 serviceProxy = nou Service1(); SoapContext requestContext = serviceProxy.RequestSoapContext; requestContext.Security.Tokens.Add(userToken);
- Adăugați-vă acreditările inserându-le într-un anumit token - al cărui tip aparține spațiului de nume Microsoft.Web.Services2.Security.Tokens
- Creați un proxy pentru serviciul dvs. (în exemplul de mai sus serviceProxy)
- Accesați antetul solicitării dvs. prin serviciul dvs. RequestSoapContext
- Adăugați token la cerere
De asemenea, cred că ați putea sări peste partea „? Wsdl” din adresă, deoarece se referă la specificația serviciului web. Odată ce ați terminat, puteți încerca să apelați funcția și să vedeți cum funcționează totul: dacă funcția ar trebui să returneze ceva, verificați la ce vă așteptați.
Sunt obișnuit să scriu cod PHP, dar nu folosesc des codificare orientată pe obiecte. Acum trebuie să interacționez cu SOAP (ca client) și nu pot obține corect sintaxa. Am un fișier WSDL care îmi permite să configurez corect o nouă conexiune folosind clasa SoapClient. Cu toate acestea, nu reușesc să efectuez apelul corect și să recuperez datele. Trebuie să trimit următoarele date (simplificate):
- ID de contact
- Nume de contact
- Descriere generală
- Sumă
Există două funcții în documentul WSDL, dar am nevoie doar de una ("FirstFunction" de mai jos). Iată scriptul pe care îl rulez pentru a obține informații despre funcțiile și tipurile disponibile:
$client = new SoapClient("http://example.com/webservices?wsdl"); var_dump($client->__getFunctions()); var_dump($client->__getTypes());
Și iată rezultatul pe care îl generează:
Array( => "FirstFunction Function1(FirstFunction $parametri)", => "SecondFunction Function2(SecondFunction $parametri)",); array( => struct Contact ( id id; nume nume; ) => șir „descriere șir” => șir „cantitate int” )
Să presupunem că vreau să apelez FirstFunction cu date:
- ID de contact: 100
- Persoana de contact: Ioan
- Descriere generală: Baril de petrol
- Suma: 500
Care ar fi sintaxa corectă? Am încercat tot felul de variante, dar se pare că structura săpunului este destul de flexibilă, așa că există doar atâtea moduri de a face acest lucru. Nu am putut să-mi dau seama din manual...
UPDATE 1: Exemplu de probă de la MMK:
$client = new SoapClient("http://example.com/webservices?wsdl"); $params = array("id" => 100, "name" => "Ioan", "descriere" => "Baril de petrol", "cantitate" => 500,); $răspuns = $client->__soapCall(„Funcția1”, matrice($params));
Dar primesc acest răspuns: Obiectul nu are nicio proprietate „Contact”. După cum puteți vedea în rezultatul getTypes() , există o structură numită Contact , așa că cred că trebuie să clarific cumva că parametrii mei includ datele de contact, dar întrebarea este: cum?
UPDATE 2: Am încercat și aceste structuri, aceeași eroare.
$params = array(array("id" => 100, "nume" => "Ioan",), "Baril de petrol", 500,);
De asemenea, ca:
$params = array("Contact" => array("id" => 100, "nume" => "Ioan",), "descriere" => "Baril de petrol", "cantitate" => 500,);
Eroare în ambele cazuri: obiectul nu are proprietatea „Contact”.
8 răspunsuri
Aceasta este ceea ce trebuie să faci.
Doar ca să știu, am încercat să refac situația ta...
- În acest exemplu, am creat un serviciu web .NET folosind o WebMethod numită Function1 și aceștia sunt parametrii:
Funcția1 (pin pin, descriere șir, număr int)
În care Contact are doar o clasă bean care are getters și setters pentru id și nume, ca în cazul dvs.
Puteți încărca acest serviciu web .NET cu:
Cod.
Acesta este ceea ce trebuie să faci în lateral PHP:
(Testat și funcțional)
id = $id;
$acest->nume = $nume;
- ) ) /* Inițializați serviciul web cu WSDL dvs. */ $client = new SoapClient("http://localhost:10139/Service1.asmx?wsdl"); /* Completați obiectul dvs. de contact */ $contact = new Contact(100, "John"); /* Setează-ți parametrii pentru cerere */ $params = array("Contact" => $contact, "description" => "Baril de petrol", "cantitate" => 500,); /* Invocă metoda webservice cu parametrii tăi, în acest caz: Function1 */ $response = $client->__soapCall("Function1", array($params)); /* Tipăriți răspunsul serviciului web */ var_dump($response); ?>
De unde știu că funcționează?
- Dacă faci print_r($params); veți vedea această ieșire deoarece serviciul dvs. web așteaptă:
Array ([Contact] => Obiect de contact ( => 100 => Ioan) [descriere] => Tambur de ulei [cantitate] => 500)
- Când am depanat exemplul de serviciu web .NET, am primit următoarele:
(După cum puteți vedea, obiectul Contact nu este nul, la fel ca și alți parametri, aceasta înseamnă că solicitarea dvs. a fost finalizată cu succes din partea PHP).
Răspunsul de la serviciul web .NET a fost cel așteptat și afișat pe partea PHP:
obiect (stdClass) public "Function1Result" => string "Detaliile cererii dvs.! id: 100, nume: John, descriere: Baril de petrol, cantitate: 500" (lungime = 98)
Sper ca asta sa ajute :-)
De asemenea, puteți utiliza serviciile SOAP:
„Spania”, „CityName” => „Alicante”); $răspuns = $soapclient->getWeather($params); var_dump($răspuns); // Obțineți orașele după țară $param = array("CountryName" => "Spania"); $răspuns = $soapclient->getCitiesByCountry($param); var_dump($răspuns);
Acesta este un exemplu cu un serviciu real și funcționează.
Sper că acest lucru ajută.
Mai întâi inițializați serviciile web:
$client = new SoapClient("http://example.com/webservices?wsdl");
Apoi setați și transmiteți parametrii:
$params = array("arg0" => $contactid, "arg1" => $desc, "arg2" => $nume contact); $răspuns = $client->__soapCall(„nume metodă”, matrice($params));
Rețineți că numele metodei este disponibil în WSDL ca nume de operație, de exemplu:
[email protected]
es
Matrice 0 => șir "OrderConfirmation createOrder(OrderRequest $createOrder)" (lungime=56) matrice 0 => șir "struct OrderRequest ( Identificare de identificare; Livrare livrare; Colet; Destinatar destinatar; șir de referință; )" (lungime=130) 1 => șir "struct Identification (șir expeditor; șir hash; șir de origine; )" (lungime=75) 2 => șir "struct Delivery ( Nod from; Node to; )" (lungime=41) 3 => șir " struct Node ( țara șirului; nodul șirului; )" (lungime=46) 4 => șir "struct Parcel ( descriere șir; greutate zecimală; număr ordine șir; data ordineData; )" (lungime=93) 5 => șir "struct Receiver ( string firstName; string prenume; Adresa adresa; string email; string language; )" (lungime=106) 6 => string "struct Adresa ( string line1; string line2; string postalCode; string city; string country; )" (lungime =99) 7 => șir „struct OrderConfirmation (string trackingNumber; șir de referință; )” (lungime=71) 8 => șir „struct OrderServiceException ( șir de cod;
OrderServiceException faultInfo;
mesaj șir; )" (lungime=97) Madrid Deci in codul meu:
$client = new SoapClient("http://packandship-ws.kiala.com/psws/order?wsdl");
$params = array("reference" => $orderId, "identification" => array ("sender" => param ("kiala", "sender_id"), "hash" => hash ("sha512", $orderId . param("kiala", "sender_id") , param("kiala", "parolă"), "originator" => null,), "delivery" => array ("de la" => matrice ("țară" =. > "es", "nod" => "",), "to" => array("country" => "es", "node" => "0299"),), "parcel" => array( "description" => "Descriere", "greutate" => 0.200, "orderNumber" => $orderId, "orderDate" => data ("A-m-d")), "receiver" => array ("firstName" => " Prenume client", "surname" => "Nume de familie client", "address" => array("line1" => "Linia 1 Adresa", "line2" => "Linia 2 Adresa", "postalCode" => 28006, "city" => "Madrid", "country" => "es",), "email" => "
", "limba" => "es")); $rezultat = $client->createOrder($params); var_dump($rezultat);
"; ?>SOAP (Simple Object Access Protocol) este un protocol bazat pe XML conceput pentru a face schimb de informații structurate între aplicații distribuite prin protocoalele web existente, cum ar fi HTTP. Specificația SOAP definește formatul utilizat de mesajele XML, modul în care acestea trebuie procesate, un set de reguli de codificare pentru standard, tipuri de date și convenții pentru apelurile de procedură de la distanță și răspunsurile la apeluri.
Serviciile web sunt o tehnologie la modă și modernă. Lista tehnologiilor legate de serviciile web crește aproape zilnic, dar SOAP este probabil cea mai importantă dintre ele. Acesta devine rapid protocolul standard pentru accesarea serviciilor web. Utilizează mesaje XML pentru a face schimb de informații între punctele finale, oferind în același timp unele dintre beneficiile protocoalelor binare.
Suportul RPC (Remote Procedure Calls) a fost una dintre caracteristicile minore ale protocolului SOAP la început, dar acum a devenit una dintre caracteristicile cele mai frecvent utilizate.
Extensia SOAP pentru PHP 5 este prima încercare de a organiza suportul SOAP în PHP în C. Are mai multe avantaje față de implementările SOAP existente scrise în PHP, dintre care cel mai important este viteza. În prezent, extensia este considerată experimentală, dar treptat va deveni mai fiabilă și mai stabilă.
Extensia SOAP implementează subseturi mari ale specificațiilor SOAP 1.1, SOAP 1.2 și WSDL 1.1. Scopul principal este de a profita la maximum de capabilitățile RPC ale SOAP. WSDL este folosit ori de câte ori este posibil pentru a simplifica implementarea serviciilor web.
Primul client SOAP
- Pentru a demonstra crearea unui client SOAP simplu, folosim serviciul demonstrativ „Delayed Stock Quote” de pe site-ul web XMethods. Înainte de a începe să scriem cod PHP, trebuie să colectăm următoarele informații despre acest serviciu special:
- Numele metodei
- URL unde se află acest serviciu
- Valoarea antetului metodei SOAPAction
- Spațiul de nume al metodei
Nume și tipuri de parametrii de intrare și de ieșire ale metodei
Din fericire, toate aceste informații sunt disponibile pe site-ul XMethods la http://www.xmethods.com/ din profilul RPC al serviciului: | Numele metodei |
getQuote | Adresa URL a serviciului |
http://66.28.98.121:9090/soap | SAAPUNActiune |
urn:xmethods-delayed-quotes#getQuote | Spațiul de nume al metodei |
urn:xmethods-delayed-quotes | Parametrii de intrare |
Simbol (șir) | Parametrii de ieșire |
Rezultat (float)
Exemplul 1 (client1.php)
$client = SoapClient nou (NULL,
„locație” => „http://66.28.98.121:9090/soap”,
"uri" =>
"style" => SOAP_RPC ,
„utilizați” => SOAP_ENCODED
));
Print($client -> __call (
/* Numele metodei SOAP */
"getQuote"
/* Parametri */
matrice(
SoapParam nou(
/* Valoarea parametrului */
"ibm"
/* Numele parametrului */
"simbol"
)),
/* Opțiuni */
matrice(
/* Spațiul de nume al metodei SOAP */
"uri" => "urn:xmethods-delayed-quotes" ,
/* Antet HTTP SOAPAction pentru o metodă SOAP */
"sapaction" => „urn:xmethods-delayed-quotes#getQuote”
)). „\n” );
?>
După cum puteți vedea, rezolvarea acestei probleme simple a necesitat destul de multă muncă.
Din fericire, serviciile web se pot descrie clienților folosind WSDL, ceea ce este în general destul de convenabil. WSDL pentru serviciul „Cotație întârziată” este prezentat pe pagina sa de informații de pe site-ul xmethods.com - http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl.
Iată o versiune a aceluiași client, rescrisă pentru a funcționa folosind acest document WSDL. Aici nu mai trebuie să specificăm URI-ul serverului, spațiul de nume, antetul SOAPAction, metoda de codificare și tipurile de parametri. Toate aceste informații sunt preluate din fișierul WSDL.
Exemplul 2 (client2.php)
$client = nou
SoapClient(
„http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl”
);
Print($client -> getQuote("ibm" ));
?>
E puțin mai ușor așa, nu?
Ce probleme apar la utilizarea WSDL?
Singurul argument împotriva utilizării acestuia este că clientul trebuie să citească WSDL de pe server înainte de a putea fi apelată orice procedură, iar pe web acest lucru poate dura destul de mult. Pentru a accelera munca, extensia SOAP oferă următorii parametri de configurare: soap.wsdl_cache_enabled, soap.wsdl_cache_dir și soap.wsdl_cache_ttl. Acestea pot fi setate în fișierul php.ini sau folosind ini_set() (vezi Exemplul 4). În mod implicit, memorarea în cache WSDL este activată, iar fișierele WSDL sunt stocate în cache timp de 1 zi.
Aici este secțiunea SOAP a fișierului php.ini cu valorile implicite. Le puteți copia în php.ini.
[săpun]
;
Săpun. wsdl_cache_enabled = „1”
activează sau dezactivează stocarea în cache WSDL
;
Săpun. wsdl_cache_dir = "/tmp"-
specifică numele directorului în care SOAP
extensia va stoca fișiere stocate în cache
Săpun. wsdl_cache_ttl = "86400" ; (durata de viață) stabilește ora (în secunde)
ce fișiere din cache pot fi utilizate
Primul server SOAP
Primul lucru pe care trebuie să-l facem este să creăm un document WSDL care să descrie serviciul nostru într-un format pe care clienții îl pot înțelege. Pentru a face acest lucru, va trebui să modificați ușor documentul original preluat de pe site-ul web Xmethods, așa că vom începe prin a-l privi mai detaliat.
Secțiunea de mesaje definește două mesaje. Primul este getQuoteRequest, care transmite mesajul getQuote și acceptă un parametru de o linie numit simbol. Al doilea mesaj este getQuoteResponse, un răspuns la o solicitare getQuote care transmite o singură valoare flotantă numită Result.
Secțiunea portType definește o singură operație, getQuote, care specifică care dintre cele descrise în secțiunea mesaj vor fi folosite pentru cerere și care pentru răspuns.
Secțiunea de legare definește modul în care mesajul ar trebui să fie codificat și transmis. În acest caz, se precizează că vom trimite o solicitare RPC prin HTTP folosind codificare SOAP. De asemenea, definește spațiul de nume și valoarea antetului SOAPAction pentru metoda getQuote.
În cele din urmă, secțiunea de servicii definește adresa URL la care se află serviciul.
Exemplul 3 (stockquote.wsdl)
xmlns:tns=" http://example.org/StockQuote "
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
Notă: Memorarea în cache WSDL este activată în mod implicit. În timpul dezvoltării și depanării WSDL-ului, este mai bine să dezactivați stocarea în cache.
Acum este momentul să începem crearea serverului nostru.
În primul rând, vom dezvolta o funcție getQuote() care va gestiona cererile primite de pe web. În continuare, vom crea un obiect al clasei SoapServer și vom atașa funcția noastră utilizând metoda SoapServer::addFunction(). După cum veți vedea mai târziu, constructorul SoapServer() are un singur parametru - calea către documentul WSDL care descrie serviciul.
Exemplul 4 (server1.php)
$ghilimele = matrice(
"ibm" => 98.42
);
global $ghilimele ;
returnează $ghilimele [ $simbol ];
}
Ini_set ( "soap.wsdl_cache_enabled" , "0" ); // dezactivează memoria cache WSDL
$server = new SoapServer("stockquote1.wsdl");
$server -> addFunction("getQuote");
$server -> handle();
?>
SoapServer poate funcționa fără WSDL în același mod ca un client, dar nu există avantaje în utilizarea acestei opțiuni care să o facă să merite să fie folosită. Dacă tot doriți să lucrați în acest fel, trebuie să vă asigurați că valorile returnate sunt obiecte ale claselor SoapParam și SoapVar (ca în primul exemplu.
Iată un client pentru a accesa serverul nostru SOAP. În comparație cu exemplul anterior, a fost adăugat doar linkul de locație WSDL. Se presupune că fișierul „stockquote1.wsdl” se află în același director cu serverul SOAP.
Exemplul 5 (client3.php)
$client = new SoapClient("stockquote1.wsdl");
print($client -> getQuote("ibm" ));
?>
Care sunt principalele probleme cu clientul și serverul nostru?
Pentru început, nu se ocupă de erori. Ce se întâmplă atunci când serverul nu găsește un rezultat potrivit pentru valoarea variabilei simbol care i-a fost transmisă? SOAP are un format de mesaj special pentru mesajele de eroare - SoapFault Pentru a genera un astfel de mesaj, serverul trebuie să lanseze o excepție folosind obiectul SoapFault. Primul parametru al constructorului SoapFault() este un șir cu un cod de eroare, al doilea este un șir cu o descriere a erorii. Clientul trebuie să fie scris pentru a gestiona excepțiile SoapFault.
În al doilea rând, este mai bine să încapsulați funcționalitatea serviciului web într-o clasă PHP. În acest caz, nu va trebui să folosim variabile globale și să adăugăm fiecare metodă SOAP la server separat. În schimb, vom putea adăuga întreaga clasă și toate metodele acesteia vor fi disponibile prin SOAP. Iată versiunile modificate corespunzător ale clientului și serverului.
Exemplul 6 (server2.php)
clasa QuoteService(
private $quotes = array("ibm" => 98.42 );
Funcția getQuote ($simbol) (
if (isset($this -> ghilimele [ $simbol ])) (
returnează $acest -> ghilimele [ $simbol ];
) altfel (
arunca noua SoapFault("Server" , "Simbol necunoscut "$simbol"." );
}
}
}
$server = new SoapServer("stockquote2.wsdl");
$server -> setClass("QuoteService");
$server -> handle();
?>
După cum puteți vedea, am folosit metoda SoapServer::setClass() pentru a conecta obiectul SoapServer la clasa QuoteService.
Exemplul 7 (client4.php)
$client = new SoapClient("stockquote2.wsdl");
incearca (
ecou"
\n" ;\n" ;
print($client -> getQuote("ibm" ));
ecou „\n” ;
print($client -> getQuote("microsoft" ));
ecou „\n
) catch (SoapFault $exception ) (
echo $exceptie ;
}
?>
Ce este înăuntru?
Dacă doriți să înțelegeți formatul mesajelor SOAP sau doriți să depanați singur un client SOAP, atunci această secțiune este pentru dvs.
După cum ați văzut în primul exemplu, constructorul SoapClient() ia un tablou asociativ ca al doilea parametru. Cu această matrice putem apela diverse opțiuni pe server.
Să ne uităm la două dintre ele:
- urmărire - permite clientului să salveze cererile și răspunsurile SOAP (dezactivate implicit).
- excepții - permite clientului să controleze mecanismul de excepție (activat implicit).
Să ne uităm la următorul exemplu de client SOAP. Aceasta este o extindere a clientului din Exemplul 5, arătând exact ce se trece între client și server. Pentru a obține aceste informații, sunt utilizate metodele __getLastRequest() și __getLastResponse().
Exemplul 8 (client5.php)
$client = new SoapClient("stockquote1.wsdl" ,array(
"urme" => 1 ,
„excepții” => 0 ));
$client -> getQuote("ibm");
printeaza "
\n" ;" ;
imprimați „Interogare:\n” . htmlspecialchars ($client -> __getLastRequest ()) . „\n” ;
imprimați „Răspuns:\n” . htmlspecialchars($client -> __getLastResponse()). „\n” ;
printeaza "
?>
Iată rezultatul scriptului. A fost ușor modificat pentru a fi mai ușor de înțeles.
Cerere:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
Răspuns:
xmlns:ns1="urn:xmethods-delayed-quotes"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
Alte implementări SOAP pentru PHP
Toate sunt scrise în PHP, nu în C.
Relua
În acest articol, am descris doar funcțiile de bază ale extensiei SOAP. De fapt, poate face mult mai mult, dar este pur și simplu imposibil să-și demonstreze toate capacitățile într-un articol scurt. Iată o listă a celor principale:
- Suport pentru tipuri de date complexe (matrice, obiecte)
- Suport antet SOAP
- Suport dinamic pentru SOAP 1.1 și SOAP 1.2
Poate că acestea vor fi discutate mai detaliat în articolele următoare.
Documentația detaliată despre extensia SOAP se găsește la http://www.php.net/manual/en/ref.soap.php.
Dezvoltarea acestei extensii este în fazele sale incipiente, astfel încât feedbackul dvs. va ajuta să o faceți mai stabilă, fiabilă, convenabilă și mai rapidă. Vă rugăm să raportați orice problemă pe care o întâlniți când îl utilizați la http://bugs.php.net/.
Legături
Despre autor
Pentru a crea un serviciu web SOAP în PHP, mai întâi trebuie să instalați și să configurați PHP, precum și un server HTTP local. În acest proiect, a fost folosit pachetul XAMP, care permite instalarea rapidă a serverului HTTP Apache și PHP.
Separat, trebuie să faceți modificări la fișierele de configurare Apache și PHP.
În fișierul de configurare a serverului HTTP Apache httpd.conf, trebuie să găsiți următorul fragment de cod:
Pentru a rula scripturi PHP pe un server local, trebuie să le stocați în directorul rădăcină al serverului Apache, în mod implicit, folderul htdocs din folderul rădăcină Apache.
Pentru a schimba directorul rădăcină al site-ului, trebuie să faceți modificări fișierului httpd.conf în linia de mai jos:
Pentru a activa suportul PHP, trebuie să adăugați următoarele linii în fișierul httpd.conf:
Pentru a lansa serverul Apache HTTP, puteți utiliza comenzile consolei sau panoul de control XAMMP, care vă permite să gestionați starea Apache și, de asemenea, să o configurați.
Aspectul acestui utilitar este prezentat în Figura 2.
Figura 2. - Utilitarul XAMMP Control Panel:
Pentru a crea un serviciu web SOAP, trebuie să scrieți documente PHP care implementează părțile client și server ale aplicației, precum și o pagină WSDL pentru a descrie serviciul web.
Să creăm un serviciu web care oferă un serviciu web care returnează clientului rezultatul unei operații aritmetice pe două numere. Elementele de intrare sunt două numere specificate de client, precum și o variabilă simbolică care definește o operație aritmetică.
Partea client este implementată de două documente PHP. În fișierul form.php folosind elementul