Sunteți pe pagina 1din 26

Servicii Web cu PHP

• SOAP (Simple Object Access Protocol) permite construirea de


software interoperabil care incurajeaza utilizarea unui cod in retea.
• Acesta defineste reguli pentru trimiterea si primirea de Remote
Procedure Calls (RPC) cum ar fi structura unei cereri sau a unui
raspuns.
• SOAP nu este legat de nici o un sistem de operare si de nici un limbaj
de programare.
• Un mesaj SOAP poate fi procesat in orice limbaj de programare.
Structura unui mesaj SOAP

• SOAP se bazeaza pe XML si de aceea este considerat ca poate fi citit


de oameni, dar trebuie sa adere la o schema specifica.

• In continuare este prezentat un mesaj SOAP fara date, pentru a putea


analiza elementele sale componente.
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
• Acesta este un fisier XML obisnuit, care are elementul root Envelope cu
name space-ul soap cu adresa: http://www.w3.org/2001/12/soap-
envelope.

• Atributul soap:encodingStyle determina tipurile datelor utilizate in fisier,


dar SOAP nu are o codare implicita.

• soap:Envelope este obligatoriu, dar urmatorul element, soap:Header, este


optional si de regula contine informatii relevante pentru autentificare sau
gestionarea sesiunilor.

• Protocolul SOAP nu ofera nici o autentificare intrinseca, dar permite


dezvoltatorilor sa o includa in eticheta header.
• Apoi urmeaza elemental obligatoriu soap:Body care contine mesajul
RPC, inclusiv numele metodelor si, in cazul unui raspuns, valorile
returnate ale metodei.

• Elementul soap:Fault este optional; daca este prezent acesta retine


mesajele de eroare sau informatii legate de statusul mesajului SOAP si
trebuie sa fie un element copil al elementului soap:Body.

• Sa scriem in continuare o cerere SOAP.


<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.yourwebroot.com/stock">
<m:GetStockPrice>
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
• Acesta este un exemplu de mesaj de cerere SOAP pentru a obtine pretul
actiunilor unei anumite companii.

• In elementul soap:Body observam elementul GetStockPrice care este specific


aplicatiei.

• Acesta nu este un element SOAP, si isi ia numele de la functia de pe server


care va fi apelata pentru aceasta cerere.

• StockName este deasemenea specific acestei aplicatii si este un argument al


functiei.

• Mesajul de raspuns este similar cu cel de cerere:


<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.yourwebroot.com/stock">
<m:GetStockPriceResponse>
<m:Price>183.08</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>
• In elementul soap:Body este un element GetStockPriceReponse cu
un element copil Price care contine datele returnate.

• Ambele elemente GetStockPriceReponse si Price sunt specifice


aplicatiei.

• In continuare vom instala NuSOAP si vom construi un client si un


server SOAP pentru a demonstra cum se genereaza astfel de mesaje.
Construirea unui server SOAP
• Descarcati libraria NuSOAP de la adresa:
sourceforge.net/projects/nusoap, si dezarhivati-o in directorul root.
Apoi va trebui sa includeti fisierul nusoap.php in codurile viitoare.

• In cazul serverului sa presupunem ca trebuie sa construim un serviciu


care sa furnizeze o lista de produse dintr-o anumita categorie, atunci
cand este dat un produs din acea categorie.
• Serverul va trebui sa citeasca categoria dintr-o cerere, sa caute daca
sunt produse din categoria respectiva si sa returneze lista in format
CSV.

• Sa cream un fisier un directorul root numit productlist.php :


<?php
require_once "nusoap-0.9.5/lib/nusoap.php";

function getProd($category) {
if ($category == "books") {
return join(",", array(
"The WordPress Anthology",
"PHP Master: Write Cutting Edge Code",
"Build Your Own Website the Right Way"));
}
else {
return "No products listed under that category";
}
}

$server = new soap_server();


$server->register("getProd");
$server->service($HTTP_RAW_POST_DATA);
?>
• Fisierul nusoap.php este inclus pe prima linie pentru a putea utiliza
biblioteca NuSOAP.
• Apoi este definita functia getProd() si este instantiata clasa soap_server.
• Functia getProd() este inregistrata utilizand metoda register().

• Intr-un scenariu real functia getProd() poate cauta cartile intro baza de date,
dar aici am returnat un mesaj, pentru a ne concentra pe mecanismul SOAP.
• Pentru a adauga mai multa functionalitate serverului va trebui sa definim
functii aditionale (sau metode ale claselor) si sa le inregistram ca mai inainte.

• Pana acum am construit un server functional. Sa construim in continuare un


client.
Construirea unui client SOAP
Creati un fisier numit productlistclient.php ca mai jos:

<?php
require_once "nusoap-0.9.5/lib/nusoap.php";
$client = new
nusoap_client("http://localhost/PhpProject1/productlist.php");

$error = $client->getError();
if ($error) {
echo "<h2>Constructor error</h2><pre>" . $error . "</pre>";
}

$result = $client->call("getProd", array("category" => "books"));


if ($client->fault) {
echo "<h2>Fault</h2><pre>";
print_r($result);
echo "</pre>";
}
else {
$error = $client->getError();
if ($error) {
echo "<h2>Error</h2><pre>" . $error . "</pre>";
}
else {
echo "<h2>Books</h2><pre>";
echo $result;
echo "</pre>";
}
}
?>
• Am inclus nusoap.php cu instructiunea require once si apoi am creat o noua
instanta a nusoap_client.
• Constructorul are ca argument adresa serverului SOAP nou creat la care
urmeaza sa se conecteze.
• Metoda getError() verifica daca clientul a fost creat correct si afiseaza un
mesaj de eroare in caz contrar.
• Metoda call() genereaza si trimite cereri SOAP pentru a apela metoda sau
functia definite de primul argument.
• Al doilea argument al call() este un sir asociativ de argumente pentru RPC.
• Proprietatea fault si metoda getError() sunt utilizate pentru a verifica si afisa
orice eventuala eroare.
• Daca nu sunt erori, rezultatul functiei este afisat.
• Acum puneti ambele fisiere in directorul root si executati script-ul client
(http://localhost/PhpProject1/productlistclient.php) .
• Daca vreti sa vizualizati cererea si raspunsul SOAP pentru debug,
adaugati urmatoarele linii in finalul fisierului productlistclient.php:

echo "<h2>Request</h2>";
echo "<pre>" . htmlspecialchars($client->request, ENT_QUOTES) .
"</pre>";
echo "<h2>Response</h2>";
echo "<pre>" . htmlspecialchars($client->response, ENT_QUOTES) .
"</pre>";

• Headerele HTTP si continutul XML vor fi adaugate al output astfel:


WSDL(Web Services Description Language)
Ce sunt fisierele WSDL?

• Fisierele Web Services Description Language (WSDL) sunt documente


XML care furnizeaza metadata despre serviciile SOAP.
• Acestea contin informatii despre functiile sau metodele pe care
aplicatiile le fac disponibile si ce argumente sa pot utiliza.
• Facand fisiere WSDL disponibile pentru utilizatorii serviciului, acestia
au acces la definitiile necesare pentru a trimite cereri valide.
• Daca doriti ca altii sa utilizeze serviciul vostru, ar trebui sa incorporti
WSDL in serviciul SOAP.
Structura WSDL
• Ca si mesajele SOAP, fisierele WSDL au o schema specifica care trebuie sa o respecte.
• Sa consideram urmatorul fisier valid WSDL si sa ii analizam continutul.

<definitions>
<types>
........
</types>
<message>
<part></part>
</message>
<portType>
.......
</portType>
<binding>
....
</binding>
<service>
....
</service>
</definitions>
• Elementul root al fisierului WSDL este elementul “definitions”.
• Acest lucru are sens deoarece un fisier WSDL reprezinta definitia unui
serviciu web.
• Elementul types descrie tipurile de date utilizate, care in cazul WSDL, este
XML schema.
• Elementul messages contine definitiile elementelor ce reprezinta datele
serviciului.
• Elementul portType defineste operatiile care pot fi executate cu serviciul
web si mesajele de cerere si raspuns care sunt utilizate.
• Elementul binding contine protocolul si specificarea formatului datelor
pentru un portType particular.
• Elementul service defineste adresa serviciului.
• In WSDL 2.0 terminologia este putin modificata. De exemplu portType se
numeste acum Interface.
Construirea unui fisier WSDL

• Este dificil de creat fisire WSDL manual, dar NuSOAP poate genera
fisier WSDL.

• Vom modifica serverul SOAP anterior pentru a utiliza si WSDL.

• Modificati fisierul productlist.php astfel:


<?php
require_once "nusoap-0.9.5/lib/nusoap.php";

function getProd($category) {
if ($category == "books") {
return join(",", array(
"The WordPress Anthology",
"PHP Master: Write Cutting Edge Code",
"Build Your Own Website the Right Way"));
}
else {
return "No products listed under that category";
}
}
$server = new soap_server();
$server->configureWSDL("productlist", "urn:productlist");

$server->register("getProd",
array("category" => "xsd:string"),
array("return" => "xsd:string"),
"urn:productlist",
"urn:productlist#getProd",
"rpc",
"encoded",
"Get a listing of products by category");

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';


$server->service($HTTP_RAW_POST_DATA);

?>
• Prima modificare este adaugarea unui apel al functiei configureWSDL();

• metoda functioneaza ca un flag care spune serverului sa genereze un


fisier WSDL pentru serviciul nostru.

• Primul argument este numele serviciului si al doilea este namespace-ul


serviciului nostru.

• Nu discutam aici detalii despre namespace-uri dar platformele Apache


sau .NET le folosesc.

• Cel mei bine este sa le folosim pentru interoperabilitate.


• A doua modificare adauga argumente aditionale la metoda register().
• getProd este numele functiei
• array("category" => "xsd:string") defineste argumentul input a functiei
getProd() si tipul sau de date
• array("return" => "xsd:string") defineste valoarea returnata de functie si
tipul sau de date
• urn:productlist defineste namespace-ul
• urn:productlist#getProd defineste actiunea SOAP
• rpc defineste tipul de apel si poate avea valoarile rpc sau document
• encoded defineste valoarea pentru atributul use; valori posibile sunt encoded
sau literal
• ultimul parametru este un string documentation care descrie ce face functia
getProd()
• Acum deschideti adresa http://localhost/PhpProject2/productlist.php?wsdl si
veti vedea un fisier WSDL. Copiati sursa si salvati-o intr-un fisier propriu numit
products.wsdl pe care il salvati in directorul web.
Lucrul cu fisiere WSDL in partea client
• Am modificat serverul SOAP pentru a genera fisiere WSDL. Acum vom
modifica clientul SOAP pentru a-l utiliza.
• Deschideti productlistclient.php si modificati linia care initializeaza clientul:
$client = new nusoap_client("http://localhost/PhpProject1/productlist.php");
astfel:
$client = new nusoap_client("products.wsdl", true);
• Al doilea parametru al constructorului nusoap_client() ii spune lui NuSOAP
sa constuiasca un client SOAP care sa accepte fisierul WSDL.
• Acum deschideti productlistclient.php si veti obtine acesasi rezultat ca mai
inainte dar utilizand WSDL!
• http://localhost/PhpProject2/productlistclient.php

S-ar putea să vă placă și