SOAP: Együttműködés távoli szolgáltatásokkal
Néhány hete jelent meg - a Kiskapu gondozásában magyar fordításban is elérhető - Advanced PHP Programming című könyv távoli szolgáltatások használatával foglalkozó fejezetének első része webhelyünkön. A PHP fejlesztés felsőfokon címen megjelent könyv ezen fejezete a SOAP technológia ismertetésével folytatódik, rátérve a WSDL praktikáira, majd végül összehasonlítja az XML-RPC és SOAP megoldásokat.A SOAP eredetileg a Simple Object Access Protocol (egyszerű objektumelérési protokoll) rövidítése volt, de az 1.1-es változattól önállósult. A SOAP egy olyan protokoll, amely alkalmas változatos környezetbeli adatcserék lebonyolítására. Az XML-RPC-től eltérően, ami kifejezetten az RPC-k kezelésére hivatott, a SOAP általános üzenetkezelésre készült, így az RPC-k ügye csak egyike a számos alkalmazásának. Mindazonáltal, fejezetünk az RPC-kről szól, így most csak a SOAP 1.1 hozzájuk kapcsolódó részéről szólunk.
Hogy is néz ki a SOAP? Íme egy SOAP boríték, amely az xmethods.net tőzsdei árfolyam- lekérdező SOAP szolgáltatását alkalmazza a hivatalos bemutató példa megvalósítására, vagyis az IBM tőzsdei árfolyamának lekérdezésére (azért hivatalos , mert ez a példa szerepel a SOAP bemutató leírásában):Íme a válasz:A SOAP esete jól példázza azt, hogy egy egyszerű elgondolás nem feltétlenül jár együtt egyszerű megvalósítással. A SOAP üzenet egy borítékból áll, ami egy fejlécet és egy üzenettörzset tartalmaz. Minden elem névtereken található, ami nagyszerű gondolat, de nehézkessé teszi az XML olvasását.
A legkülső címke neve Envelope - ez tartalmazza magát a SOAP üzenetet. Ez az elem azEz kapcsolatot teremt a
A névterek ugyanazt a szerepet töltik be az XML-ben, amit más programozási nyelvekben: Segítenek elkerülni az ütközéseket két megvalósítás neve között. Vegyük a legfelső szintű címkét (
A SOAP
Figyeljük meg a Schema használatát a tőzsdei azonosító típusmeghatározásában és elrendezésében: A
Hasonlóan, a válaszban is látható az árfolyam típusának meghatározása:Itt láthatjuk, hogy az eredmény egy lebegőpontos szám. Mindez hasznunkra lehet, hiszen a Schema érvényességi eszközeivel ellenőrizhetjük dokumentumunkat. Így például, ha a válasz a következő alakban érkezik, érvénytelennek tekintik, mivel a
Látható, hogy a WSDL sem takarékoskodik a névterek használatával, szerkezete pedig kissé felrúgni látszik a logika szabályait.
A kód első vizsgálatra érdemes része a
A
Következik a
Végezetül, a Érdemes megjegyeznünk, hogy semmi sem köti a SOAP-ot a HTTP protokollhoz, és választ sem kell feltétlenül visszaadnia. Ez egy rugalmas, általános célú protokoll, melynek a HTTP felett működő RPC csak egyik megvalósítása. A WSDL fájl arról tájékoztat, hogy milyen szolgáltatások érhetők el, és ezt hogyan és hogyan férhetünk hozzájuk. A kérelmet és a választ ezután a SOAP valósítja meg.
Szerencsére a PEAR SOAP osztályai elvégzik a munka nagyobb részét. Egy SOAP kérelem kiadásához először egy új
A A
SOAP programozói tudásunkat nyomban próbára is tehetjük - kíséreljük meg SOAP alatt megvalósítani az XML-RPC
Először is, SOAP szolgáltatásunkat a
Íme az új SOAP SystemLoad megvalósítás osztályának meghatározása:Az XML-RPC-től eltérően a
Ha meghatároztunk egy szolgáltatást, az XML-RPC-hez hasonlóan be kell jegyeztetnünk. A következő példában készítünk egy újVan tehát egy teljes értékű kiszolgálónk, de nincs még meg a WSDL fájl, melyből az ügyfelek megtudhatnák, hogyan férhetnek hozzá ehhez a kiszolgálóhoz. Ennek elkészítése nem nehéz feladat - csak sok időbe telik. Lássuk, milyen eredményre számíthatunk:Nos, itt nem sok újdonság bukkant fel. Figyeljük meg, hogy a névterek egybecsengenek azzal, amit a
A szolgáltatáshoz tartozó ügyfél hasonlít a tőzsdés példában látotthoz:
Mindennek bemutatására lássuk, miként kereshetünk meg egy szerzőt azA kimeneti és bemeneti üzenetek típusát itt az alábbiak szerint határozzák meg:ésMindkettő saját, a Schema-ban meghatározott típus. Íme az Ahhoz, hogy ezt a típust PHP-ben is megjeleníthessük, készítenünk kell egy erre a célra szolgáló osztályt, amely a
Lássuk tehát azA szerző szerinti keresés megvalósításához először készítenünk kell egy
Ezután hozzunk létre egy Az eredményt a Futtatása után az alábbi eredményt kapjuk:
A helyettes kód elkészítésének érdekében töltsük be az URL-t azA futtatás után az alábbi kódhoz jutunk:Mostantól a WSDL fájl értelmezése helyett közvetlenül ezt az osztályt hívhatjuk.
Ha azonban új szolgáltatást telepítünk, és szabad kezet kapunk a választásban, az alábbiakat érdemes megfontolnunk:
A http://www.soapware.org/bdg nagyszerű bevezetést ad a SOAP használatába.
Shane Caraveo webszolgáltatásokról adott előadásainak anyaga a http://talks.php.net címen segít megérteni, mi szükséges a SOAP sikeres használatához a PHP-ben. Jó tudnunk, hogy Shane a PHP 5 SOAP-megvalósításának vezető fejlesztője.
Dave Winer, az XML-RPC megalkotója egy kellemes bevezető írását a következő címen lelhetjük meg: http://davenet.scripting.com/1998/07/14/xmlRpcForNewbies.
A MetaWeblog API leírása a http://www.xmlrpc.com/metaWeblogApi címen található.
A MovableType bővítményeket kínál mind a MetaWeblog, mind a Blogger API-hez. Leírásuk a http://www.movabletype.org/docs/mtmanual_programmatic.html címen megtalálható.
Az RSS egy nyílt XML formátum tartalom-közzétételhez. Leírását a http://blogs.law.harvard.edu/tech/rss címen lelhetjük meg.
Az XML-RPC példáinkban szereplő Serendipity webnaplózó rendszer a http://www.s9y.org címen érhető el.
Az Amazon rendelkezik egy szabad SOAP felülettel. A részletekről a http://www.amazon.com/gp/aws/landing.html címen érdeklődhetünk.
A Google is rendelkezik szabad SOAP keresőfelülettel. Erről a http://www.google.com/apis címen olvashatunk.
■ SOAP
A sorozatban megjelent
- XML-RPC: Együttműködés távoli szolgáltatásokkal
- SOAP: Együttműködés távoli szolgáltatásokkal
Hogy is néz ki a SOAP? Íme egy SOAP boríték, amely az xmethods.net tőzsdei árfolyam- lekérdező SOAP szolgáltatását alkalmazza a hivatalos bemutató példa megvalósítására, vagyis az IBM tőzsdei árfolyamának lekérdezésére (azért hivatalos , mert ez a példa szerepel a SOAP bemutató leírásában):
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
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:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<getQuote xmlns="http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote.StockQuote/">
<symbol xsi:type="xsd:string">ibm</symbol>
</getQuote>
</soap:Body>
</soap:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<n:getQuoteResponse xmlns:n="urn:xmethods-delayed-quotes">
<Result xsi:type="xsd:float">90.25</Result>
</n:getQuoteResponse>
</soap:Body>
</soap:Envelope>
A legkülső címke neve Envelope - ez tartalmazza magát a SOAP üzenetet. Ez az elem az
xmlsoap
névtérben található, amit teljes minősített nevéből (<soap:Envelope>
) és e névtér meghatározásából is láthatunk:
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
soap
és az alábbi névtér-URI között: http://schemas.xmlsoap.org/soap/envelope/
A névterek ugyanazt a szerepet töltik be az XML-ben, amit más programozási nyelvekben: Segítenek elkerülni az ütközéseket két megvalósítás neve között. Vegyük a legfelső szintű címkét (
<soap-env:Envelope>
). Az Envelope
tulajdonságnév eszerint a soap-env
névtérben található. Így hát, ha a FedEX valamilyen okból egy XML formátumot határoz meg, amely az Envelope
tulajdonságot használja, ezt nyugodtan megteheti a teljes <FedEX:Envelope>
névvel, és semmi baj nem történik.A SOAP
Envelope
-on belül négy névtér létezik:xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
- A SOAP boríték Schema meghatározása leírja az alapvető SOAP objektumokat - ez a névtér szerepel minden SOAP kérelemben.
xmlns:xsi="http://www.w3.org/21/XMLSchema-instance"
- Azxsi:type
elemtulajdonság gyakran használatos az elemek típusának megadásánál.
xmlns:xsd="http://www.w3.org/21/XMLSchema"
- A Schema megad néhány alapvető adattípust, melyeket adataink meghatározásánál és az ellenőrzésnél használhatunk.
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding"
- Ez a típuskódolások meghatározása, melyek a szabványos SOAP kérelmekben megjelennek.
<GetQuote>
elem szintén egy névtérben található - ez esetben egy meglehetősen hosszú nevűben:http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote.StockQuote
<symbol xsi:type="xsd:string">ibm</symbol>
<symbol>
karakterlánc típusú.Hasonlóan, a válaszban is látható az árfolyam típusának meghatározása:
<Result xsi:type="xsd:float">90.25</Result>
foo
nem érvényes lebegőpontos szám:
<Result xsi:type="xsd:float">foo</Result>
WSDL
A SOAP méltó párja a WSDL (Web Services Description Language - webszolgáltatás-leíró nyelv). Ez egy XML alapú nyelv, ami kifejezetten arra szolgál, hogy a webszolgáltatások (leggyakrabban a SOAP) lehetőségeit és tagfüggvényeit leírjuk. Íme egy WSDL fájl, amely a korábban már alkalmazott tőzsdei szolgáltatás leírását adja:
<?xml version="1.0" encoding="UTF-8" ?>
<definitions name="net.xmethods.services.stockquote.StockQuote"
targetNamespace= "http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote. StockQuote/"
xmlns:tns= "http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote. StockQuote/"
xmlns:electric="http://www.themindelectric.com/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
<message name="getQuoteResponse1">
<part name="Result" type="xsd:float" />
</message>
<message name="getQuoteRequest1">
<part name="symbol" type="xsd:string" />
</message>
<portType name="net.xmethods.services.stockquote.StockQuotePortType">
<operation name="getQuote" parameterOrder="symbol">
<input message="tns:getQuoteRequest1" />
<output message="tns:getQuoteResponse1" />
</operation>
</portType>
<binding name="net.xmethods.services.stockquote.StockQuoteBinding"
type="tns:net.xmethods.services.stockquote.StockQuotePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="getQuote">
<soap:operation soapAction="urn:xmethods-delayed-quotes#getQuote" />
<input>
<soap:body use="encoded" namespace="urn:xmethods-delayed-quotes"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:xmethods-delayed-quotes"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
<service name="net.xmethods.services.stockquote.StockQuoteService">
<documentation>
net.xmethods.services.stockquote.StockQuote web service
</documentation>
<port name="net.xmethods.services.stockquote.StockQuotePort"
binding="tns:net.xmethods.services.stockquote.StockQuoteBinding">
<soap:address location="http://66.28.98.121:9090/soap" />
</port>
</service>
</definitions>
A kód első vizsgálatra érdemes része a
<portType>
címke, amely meghatározza a végrehajtható műveleteket, valamint a ki- és bevitt üzeneteket. Esetünkben a getQuote
műveletet adja meg, amely a getQuoteRequest1
kérelmet fogadja, és a getQuoteResponse1
választ adja vissza.A
getQuoteResponse1
<message>
címkéi szerint tartalma egyetlen, float
típusú Result
elem. Hasonlóképpen, a getQuoteRequest1
egyetlen string
típusú symbol
elemet tartalmaz.Következik a
<binding>
címke. A <portType>
-hoz a type
tulajdonságon keresztül kapcsolódik egy kötés, amely megegyezik a <portType>
nevével. A kötések a protokoll és az adatátvitel tulajdonságait határozzák meg (például a SOAP üzenet törzsében elhelyezett adatok kódolását), de a címeket nem. Egy kötés egyetlen protokollhoz tartozhat - esetünkben a HTTP-hez, kapcsolatukat az alábbi kód adja meg:
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<service>
címke felsorol néhány kaput, és címeket határoz meg számukra. Mivel esetünkben csak egyetlen kaput használunk, a következő kóddal hivatkozunk rá és kötjük a http://66.28.98.121:9090/soap
címhez:
<port name="net.xmethods.services.stockquote.StockQuotePort"
binding="tns:net.xmethods.services.stockquote.StockQuoteBinding">
<soap:address location="http://66.28.98.121:9090/soap" />
</port>
Szerencsére a PEAR SOAP osztályai elvégzik a munka nagyobb részét. Egy SOAP kérelem kiadásához először egy új
SOAP_Client
ügyfélobjektumot kell készítenünk, és át kell adnunk a WSDL fájlt az elérni kívánt szolgáltatásokkal. A SOAP_Client
ezután elkészíti az összes szükséges helyettes kódot a közvetlenül végrehajtott kérelmekhez, legalábbis olyan esetekben, amikor az adatok mind egyszerű Schema típusoknak feleltethetők meg. Az alábbiakban bemutatunk egy teljes ügyfélkérelmet az xmethods.net
tőzsdei szolgáltatásához:
<?php
require_once "SOAP/Client.php";
$url = "http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl";
$soapclient = new SOAP_Client($url, true);
$price = $soapclient->getQuote("ibm")->deserializeBody();
print "Current price of IBM is $price\n";
?>
SOAP_Client
ezután átvállalja a helyettes objektum készítésének terhét, mellyel közvetlenül futtathatjuk a WSDL-ben megadott tagfüggvényeket. A getQuote()
hívását követően a rendszer kicsomagolja az eredményt, és a PHP saját típusaiba írja a deserializeBody() segítségével. A futtatáskor az alábbi eredményt kapjuk:
> php delayed-stockquote.php
Current price of IBM is 90.25
A sysem.load
átírása SOAP szolgáltatássá
SOAP programozói tudásunkat nyomban próbára is tehetjük - kíséreljük meg SOAP alatt megvalósítani az XML-RPC sysem.load
szolgáltatását.Először is, SOAP szolgáltatásunkat a
SOAP_Service
különleges célú változataként kell megvalósítanunk. Ehhez legalább az alábbi négy függvény megvalósítására szükség van:public static function getSOAPServiceNamespace(){}
- Vissza kell adnunk az általunk meghatározott szolgáltatás névterét.
public static function getSOAPServiceName(){}
- Vissza kell adnunk szolgáltatásunk nevét.
public static function getSOAPServiceDescription(){}
- Vissza kell adnunk szolgáltatásunk leírását egy karakterlánc alakjában.
public static function getWSDLURI(){}
- Vissza kell adnunk a szolgáltatást leíró WSDL fájl URL-jét.
Íme az új SOAP SystemLoad megvalósítás osztályának meghatározása:
<?php
require_once 'SOAP/Server.php';
class ServerHandler_SystemLoad implements SOAP_Service {
public static function getSOAPServiceNamespace()
{ return 'http://example.org/SystemLoad/'; }
public static function getSOAPServiceName()
{ return 'SystemLoadService'; }
public static function getSOAPServiceDescription()
{ return 'Return the one-minute load avergae.'; }
public static function getWSDLURI()
{ return 'http://localhost/soap/tests/SystemLoad.wsdl'; }
public function SystemLoad()
{
$uptime = `uptime`;
if(preg_match("/load averages?: ([\d.]+)/", $uptime, $matches)) {
return array( 'Load' => $matches[1]);
}
}
}
?>
SOAP_Service
tagfüggvények paramétereiket hagyományos PHP változók alakjában kapják meg. Visszatéréskor mindössze a válaszüzenet patamétereinek tömbjét kell megadnunk. A névterek választásánál szabad kezet kapunk, de a rendszer ellenőrzi azokat a megadott WSDL fájl alapján, így egymással összhangban kell legyenek.Ha meghatároztunk egy szolgáltatást, az XML-RPC-hez hasonlóan be kell jegyeztetnünk. A következő példában készítünk egy új
SOAP_Server
objektumot, csatoljuk az új szolgáltatást, és utasítjuk a kiszolgálópéldányt a bejövő kérelmek kezelésére:
<?php
$server = new SOAP_Server;
$service = new ServerHandler_System_Load;
$server->addService($service);
$server->service('php://input');
?>
<?xml version='1.0' encoding='UTF-8'?>
<definitions name='SystemLoad'
targetNamespace='http://example.org/SystemLoad/'
xmlns:tns='http://example.org/SystemLoad/'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<message name='SystemLoadResponse'>
<part name='Load' type='xsd:float'/>
</message>
<message name='SystemLoadRequest'/>
<portType name='SystemLoadPortType'>
<operation name='SystemLoad'>
<input message='tns:SystemLoadRequest'/>
<output message='tns:SystemLoadResponse'/>
</operation>
</portType>
<binding name='SystemLoadBinding' type='tns:SystemLoadPortType'>
<soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='SystemLoad'>
<soap:operation soapAction='http://example.org/SystemLoad/'/>
<input>
<soap:body use='encoded'
namespace='http://example.org/SystemLoad/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded'
namespace='http://example.org/SystemLoad/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<service name='SystemLoadService'>
<documentation>System Load web service</documentation>
<port name='SystemLoadPort' binding='tns:SystemLoadBinding'>
<soap:address location='http://localhost/soap/tests/SystemLoad.php'/>
</port>
</service>
</definitions>
ServerHandler_SystemLoad
-nál láthattunk, továbbá a SystemLoad
prototípusa szerint egy Load
nevű lebegőpontos számmal tér vissza.A szolgáltatáshoz tartozó ügyfél hasonlít a tőzsdés példában látotthoz:
<?php
include("SOAP/Client.php");
$url = "http://localhost/soap/tests/SystemLoad.wsdl";
$soapclient = new SOAP_Client($url, true);
$load = $soapclient->SystemLoad()->deserializeBody();
print "One minute system load is $load\n";
?>
Amazon webszolgáltatások és összetett típusok
A SOAP egyik legnagyobb előnye az XML-RPC-vel szemben, hogy támogatja a felhasználók által meghatározott típusokat, melyeket a Schema segítségével készíthetnek el és ellenőrizhetnek. A PEAR SOAP-megvalósítása pedig képes automatikusan átírni e saját változókat a PHP típusaira.Mindennek bemutatására lássuk, miként kereshetünk meg egy szerzőt az
Amazon.com
webszolgáltatási API-jával. Az Amazon nagy hangsúlyt fektet webszolgáltatásainak megfelelő működésére, és elérhetővé teszi minden keresési lehetőségét a SOAP-on keresztül. Az Amazon API használatához fejlesztőként kell bejegyeztetnünk magunkat az Amazon webhelyén, a http://www.amazon.com/gp/aws/landing.html címen. Ha belepillantunk az Amazon WSDL fájljába, láthatjuk, hogy a szerző keresésének művelete az alábbi blokkban található (http://soap.amazon.com/schemas2/Amazon-WebServices.wsdl):
<operation name="AuthorSearchRequest">
<input message="typens:AuthorSearchRequest" />
<output message="typens:AuthorSearchResponse" />
</operation>
<message name="AuthorSearchRequest">
<part name="AuthorSearchRequest" type="typens:AuthorRequest" />
</message>
<message name="AuthorSearchResponse">
<part name="return" type="typens:ProductInfo" />
</message>
AuthorRequest
típusos meghatározása:
<xsd:complexType name="AuthorRequest">
<xsd:all>
<xsd:element name="author" type="xsd:string" />
<xsd:element name="page" type="xsd:string" />
<xsd:element name="mode" type="xsd:string" />
<xsd:element name="tag" type="xsd:string" />
<xsd:element name="type" type="xsd:string" />
<xsd:element name="devtag" type="xsd:string" />
<xsd:element name="sort" type="xsd:string" minOccurs="0" />
<xsd:element name="variations" type="xsd:string" minOccurs="0" />
<xsd:element name="locale" type="xsd:string" minOccurs="0" />
</xsd:all>
</xsd:complexType>
SchemaTypeInfo
felületet is megvalósítja. Ehhez két műveletet kell megírnunk:public static function getTypeName() {}
- Visszaadja a típus nevét.
public static function getTypeNamespace() {}
- Visszaadja a típus névterét.
Lássuk tehát az
AuthorRequest
burkolóosztályát:
<?php
class AuthorRequest implements SchemaTypeInfo {
public $author;
public $page;
public $mode;
public $tag;
public $type;
public $devtag;
public $sort;
public $variations;
public $locale;
public static function getTypeName()
{ return 'AuthorRequest';}
public static function getTypeNamespace()
{ return 'http://soap.amazon.com';}
}
SOAP_Client
helyettes objektumot az Amazon WSDL fájlból:
<?php
require_once 'SOAP/Client.php';
$url = 'http://soap.amazon.com/schemas2/AmazonWebServices.wsdl';
$client = new SOAP_Client($url, true);
?>
AuthorRequest
objektumot, és töltsük fel a keresés adataival:
<?php
$authreq = new AuthorRequest;
$authreq->author = 'schlossnagle';
$authreq->mode = 'books';
$authreq->type = 'lite';
$authreq->devtag = 'DEVTAG';
?>
ProductInfo
típusban kapjuk vissza, ami túlzottan összetett ahhoz, hogy a felépítésével itt foglalkozzunk. Mindazonáltal az alábbi rövid kóddal gyorsan utánajárhatunk, mely könyvek szerzőit hívták Schlossnagle-nek:
<?php
$result = $client->AuthorSearchRequest($authreq)->deserializeBody();
foreach ($result->Details as $detail) {
print "Title: $detail->ProductName, ASIN: $detail->Asin\n";
}
?>
Title: Advanced PHP Programming, ASIN: 0672325616
Helyettes kód készítése
Nem nehéz feladat olyan kódot írni, ami dinamikusan elkészíti a helyettes (proxy) objektumokat a WSDL-ből, de ez a folyamat meglehetősen sok értelmezési munkával jár, amit jobb elkerülni, különösen, ha egy webszolgáltatást gyakran hívnak. A SOAP WSDLkezelője képes elkészíteni a PHP kódot, így közvetlenül is lebonyolíthatjuk a hívásokat, anélkül, hogy újra és újra át kellene vizsgálni a WSDL fájlt.A helyettes kód elkészítésének érdekében töltsük be az URL-t az
MSDLManager::get()
tagfüggvénnyel, és hívjuk meg a generateProxyCode()
függvényt. Mindezt most a SystemLoad
WSDL fájl példáján mutatjuk be:
<?php
require_once 'SOAP/WSDL.php';
$url = "http://localhost/soap/tests/SystemLoad.wsdl";
$result = WSDLManager::get($url);
print $result->generateProxyCode();
?>
<?php
class WebService_SystemLoadService_SystemLoadPort extends SOAP_Client {
public function __construct()
{
parent::_ _construct("http://localhost/soap/tests/SystemLoad.php", 0);
}
function SystemLoad()
{
return $this->call("SystemLoad",
$v = array(),
array('namespace'=>'http://example.org/SystemLoad/',
'soapaction'=>'http://example.org/SystemLoad/',
'style'=>'rpc',
'use'=>'encoded' ));
}
}
A SOAP és az XML-RPC összehasonlítása
Melyik RPC protokollt alkalmazzuk - a SOAP vagy az XML-RPC mellett tegyük le voksunkat? Nos, sok esetben a körülmények nem hagynak túlzottan nagy mozgásteret. Ha olyan szolgáltatást valósítunk meg, ami meglevő ügyfelekkel vagy kiszolgálókkal érintkezik, elvesztjük a döntés lehetőségét. Így a SOAP felület használata webnaplónkban érdekes kísérlet lehet, de valószínűleg nem képes együttműködni más, már eleve meglevő eszközökkel. Ha az Amazon vagy a Google API-jaival szeretnénk együttműködni, ismét csak egyértelmű a válasz: a SOAP-ot kell használnunk.Ha azonban új szolgáltatást telepítünk, és szabad kezet kapunk a választásban, az alábbiakat érdemes megfontolnunk:
- A megvalósítás szemszögéből nézve az XML-RPC sokkal kevesebb kezdeti erőfeszítést igényel, mint a SOAP.
- Az XML-RPC kisebb dokumentumokat készít, melyek értelmezése kevésbé költséges, mint a SOAP-pal készítetteké.
- A SOAP lehetővé teszi a Schema segítségével meghatározott saját típusok használatát. Ez módot ad az adatok érvényességének hatékonyabb ellenőrzésére, valamint az automatikus típusátalakításra az XML és a PHP között. Az XML-RPC-ben mindenféle összetettebb adatcsomagolást kézzel kell elvégeznünk.
- A WSDL nagyszerű eszköz. A SOAP automatikus felderítési és helyetteskód-készítési képességei jobbak az XML-RPC-ben elérhetőknél.
- A SOAP jelentős támogatást kap az IBM-től, a Microsofttól, valamint számos, a sikerében érdekelt internetes vállalattól. Mindez azt jelenti, hogy e cégek a múltban és a jövőben is jelentős anyagi erőforrásokat és időt szentelnek arra, hogy javítsák a SOAP együttműködési készségét és a SOAP-hoz kötődő segédeszközöket fejlesszenek.
- A SOAP általános, bővíthető eszköz, míg az XML-RPC célirányos protokoll, viszonylag merev meghatározással.
További olvasmányok
A távoli szolgáltatásokkal való együttműködés témaköre igen széles, sokkal szélesebb annál, mint amennyit e fejezet átfogni képes. A SOAP különösen érdekes, fejlődő szabvány; maga is megérdemelne egy külön könyvet. A következőkben néhány hasznos forrásmunkát mutatunk be, témakörök szerint csoportosítva.SOAP
A SOAP leírása megtalálható a http://www.w3.org/TR/SOAP/ címen.A http://www.soapware.org/bdg nagyszerű bevezetést ad a SOAP használatába.
Shane Caraveo webszolgáltatásokról adott előadásainak anyaga a http://talks.php.net címen segít megérteni, mi szükséges a SOAP sikeres használatához a PHP-ben. Jó tudnunk, hogy Shane a PHP 5 SOAP-megvalósításának vezető fejlesztője.
XML-RPC
Az XML-RPC leírása megtalálható a http://www.xmlrpc.com/spec címen.Dave Winer, az XML-RPC megalkotója egy kellemes bevezető írását a következő címen lelhetjük meg: http://davenet.scripting.com/1998/07/14/xmlRpcForNewbies.
Webnaplózás
A Blogger API leírását a http://www.blogger.com/developers/api/1_docs címen találhatjuk meg.A MetaWeblog API leírása a http://www.xmlrpc.com/metaWeblogApi címen található.
A MovableType bővítményeket kínál mind a MetaWeblog, mind a Blogger API-hez. Leírásuk a http://www.movabletype.org/docs/mtmanual_programmatic.html címen megtalálható.
Az RSS egy nyílt XML formátum tartalom-közzétételhez. Leírását a http://blogs.law.harvard.edu/tech/rss címen lelhetjük meg.
Az XML-RPC példáinkban szereplő Serendipity webnaplózó rendszer a http://www.s9y.org címen érhető el.
Nyilvánosan elérhető webszolgáltatások
A http://xmethods.net kifejezetten a webszolgáltatások fejlesztéséhez (elsősorban a SOAP és a WSDL alkalmazásokhoz) nyújt segítséget. Itt ingyenesen elérhető webszolgáltatások garmadáját találhatjuk, a szerkesztők pedig az együttműködési képességek próbára tételére hívnak fel.Az Amazon rendelkezik egy szabad SOAP felülettel. A részletekről a http://www.amazon.com/gp/aws/landing.html címen érdeklődhetünk.
A Google is rendelkezik szabad SOAP keresőfelülettel. Erről a http://www.google.com/apis címen olvashatunk.
A SOAP és a Schema
A SOAP belső működéseihez igénybe veszi a Schema segítségét, ami egy XML alapú nyelv adatszerkezetek meghatározására és ellenőrzésére. A közmegegyezés szerint egy elem teljes névtere (példáulhttp://schemas.xmlsoap.org/soap/envelope/
) egy, a névteret leíró Schema dokumentum. Ez a meghatározás azonban nem kötelező érvényű - a névtérnek még csak URL-nek sem kell lennie -, de a teljesség kedvéért ezt alkalmazzák.