XML-RPC: Együttműködés távoli szolgáltatásokkal
![XML-RPC: Együttműködés távoli szolgáltatásokkal](http://weblabor.hu/misc/fs/xmlrpc.png)
Nemsokára megjelenik George Schlossnagle Advanced PHP Programming című könyve PHP fejlesztés felsőfokon címmel a Kiskapu kiadó gondozásában. Volt szerencsénk a könyv egy eredeti angol példányát az idei budapesti PHP Konferencián ajándékként átadni, most pedig a magyar kiadó jóvoltából publikálni tudjuk a könyv egyik legjobb fejezetét, melyet sehol máshol nem érhetnek el az érdeklődők digitális formában. Ezúttal a fejezet első - XML-RPC-ről szóló - szakaszát olvashatják az érdeklődők.A távoli eljáráshívási (RPC) szolgáltatások szabványos felületet biztosítanak függvények, illetve tagfüggvények hálózaton keresztüli hívására.
A webprogramozás szinte minden területén használnak RPC-t. A webböngészőktől a webkiszolgálók felé küldött HTTP kérelmek is ilyenek, mint ahogy az adatbázis-kiszolgálóknak küldött lekérdezések is. Nos, ezek valóban távoli hívások, de nem igazán tekinthetők RPC protokollnak. Hiányzik belőlük azok általánossága és szabványossága - így például a webkiszolgálók és az adatbázisok által használt protokollok nem megoszthatók, még akkor sem, ha ugyanazon a hálózati szinten bonyolódnak.
Ahhoz, hogy valóban jól használhatóak legyenek, az RPC protokolloknak az alábbi tulajdonságokkal kell rendelkezniük:
Ezt a kérelmet a POST módszerrel elküldhetjük az XML-RPC kiszolgálónak, amely megkeresi és végrehajtja a megadott tagfüggvényt (Természetesen ezeket a dokumentumokat nem magunknak kell elkészítenünk és értelmeznünk. Számos XML-RPC megvalósítás létezik PHP alatt. Jómagam a PEAR XML-RPC osztályokat kedvelem, mert ezekhez hozzájutunk a PHP-vel (a PEAR telepítő használja őket). Következésképpen gyakorlatilag minden rendszeren jelen vannak - így nincs is igazán okunk, hogy mást keressünk. Az XML-RPC párbeszéd két részből áll: az ügyfél kérelméből és a kiszolgáló válaszából.
Beszéljünk előbb az ügyfél kódjáról. Az ügyfél készít egy kérelem dokumentumot, elküldi a kiszolgálónak, majd értelmezi a kapott választ. Az alábbi kód a korábbiakban látott kérelmet készíti el, és értelmezi az erre kapott választ:Létrehozunk egy új
Ezután készítünk egy
Ezután elküldjük az üzenetet a
Természetesen a kiszolgáló oldalán is szükség van némi kódra, ami fogadja a kérelmet, megtalálja és végrehajtja a megfelelő visszahívható függvényt, majd visszaküldi a választ. Íme egy lehetséges megoldás, amely kezeli az ügyfél kódjában megadottA PHP függvények megbirkóznak a korábban meghatározott beérkező kérelmekkel. Magunknak mindössze a system.load kérelemmel kell foglalkoznunk, melynek a
Ezután a visszahívható (callback) függvény rákerül egy kiosztási térképre, amely meghatározza, mely függvényekhez rendelje a kiszolgáló az egyes bejövő kérelmeket. A meghívandó függvényekből készítünk egy
AVagy valami hasonlót, a terhelésátlagtól függően.
Számos webnaplózó rendszer létezik, és rengeteg olyan eszköz, melyek segítenek a használatukban és a bejegyzések küldésében. Ha nem volnának szabványos eljárások, a széleskörű felhasználhatóság érdekében minden eszköznek támogatnia kellene minden webnaplót, vagy fordítva. Az ilyen kapcsolatrendszer megtartása lehetetlen, ha a benne részt vevő alkalmazások száma növekszik.
Jóllehet a webnaplók lehetőségei és megvalósításai változatosak lehetnek, lehetséges olyan szabványos műveletcsalád meghatározása, melyek a bejegyzések küldését végzik. A webnaplóknak és az eszközöknek ezek után csak a megfelelő felületet kell megvalósítaniuk, és így mindenki mindenkivel együttműködhet.
Dacára a webnaplózó rendszerek nagy számának, mindössze három webnaplóküldési API terjedt el széles körben: a Blogger API, a MetaWeblog API, valamint a MovableType API (ami valójában mindössze a MetaWeblog API bővítése). A bejegyzésküldő eszközök e három protokoll valamelyikét használják az adatátvitelhez, így ha mindegyiküket megvalósítjuk, webnaplónk képes lesz fogadni bármely eszköz bejegyzéseit. Mindez nagyszerű lehetőség arra, hogy egy új webnaplózó rendszert elfogadottá tegyünk.
Természetesen először egy webnaplózó rendszerre van szükség, melyhez ezek az API-k kapcsolódhatnak. Egy teljes webnaplózó rendszer felépítése meghaladná könyvünk kereteit, így hát megelégszünk azzal, hogy egy XML-RPC réteget adunk a Serendipity webnaplóhoz. A szóban forgó API-k a bejegyzések küldését intézik, így a Serendipity alábbi eljárásaival kell érintkezniük:A A
A MetaWeblog API több lehetőséget biztosít, mint a Blogger API, így előbbi megvalósítására teszünk kísérletet. Tagfüggvényei közül az alábbi három fontosabbat kell megemlítenünk:A
Ahelyett, hogy saját formátumot választott volna az adatbevitelhez, Dave Winer, a MetaWeblog leírásának szerzője az RSS 2.0 leírás
A szabvány emellett lehetővé teszi egyéb mezők használatát is - hivatkozásokat megjegyzésekre, egyértelmű azonosítókat, valamint kategóriákat. Mindemellett számos webnapló kibővíti az RSS szabványt, úgy, hogy az tartalmazza a
A MetaWeblog API megvalósításához a korábban említett három tagfüggvénnyel kell foglalkoznunk. Először nézzük, hogyan küldhetünk új bejegyzéseket:A
Ha a hitelesítés sikeres, a
AItt is ugyanazt a hitelesítést végezzük el, elkészítjük a
Utolsóként a
Lássuk, hogy fest a kód:
Figyeljük meg, hogy a bejegyzés kiolvasása után az
A
A függvények bejegyzéséhez egy kiosztási tömböt készítünk:
Hurrá! Programunk e pillanattól kezdve megfelel a MetaWeblog API-nak!
E kiegészítő adatok tárolására a kiszolgálónak bővítenie kell kiosztási térképét - ezt láthatjuk aE három tagfüggvény használatával kialakíthatunk egy képet az XML-RPC kiszolgáló szolgáltatásairól. Lássunk egy programot, ami egy adott kiszolgálón megadja az összes XMLRPC tagfüggvény leírását és prototípusát:Egy Serendipity webnapló-kiszolgálón futtatva a fenti programot a következő eredményt kapjuk:
Vagyis magyarul:
■ Bevezető
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
A webprogramozás szinte minden területén használnak RPC-t. A webböngészőktől a webkiszolgálók felé küldött HTTP kérelmek is ilyenek, mint ahogy az adatbázis-kiszolgálóknak küldött lekérdezések is. Nos, ezek valóban távoli hívások, de nem igazán tekinthetők RPC protokollnak. Hiányzik belőlük azok általánossága és szabványossága - így például a webkiszolgálók és az adatbázisok által használt protokollok nem megoszthatók, még akkor sem, ha ugyanazon a hálózati szinten bonyolódnak.
Ahhoz, hogy valóban jól használhatóak legyenek, az RPC protokolloknak az alábbi tulajdonságokkal kell rendelkezniük:
- Általánosság Könnyű legyen új, meghívható tagfüggvényekkel kiegészíteni.
- Szabványosság Biztosítani kell, hogy ha ismert egy tagfüggvény neve és paraméterlistája, hívása egyszerűen megvalósítható legyen.
- Könnyű értelmezhetőség Az RPC visszatérési értéke olyan kell legyen, ami könnyen átalakítható az alkalmazások megfelelő saját adattípusaira.
RPC használata nagy forgalmú webhelyeken
Jóllehet az RPC igen rugalmas eszköz, természeténél fogva lassú. Bármely folyamat, amely RPC-ket használ, azonnal szembe találja magát a távoli szolgáltatás elérhetőségének és teljesítményének korlátaival. A legjobb esetben is számíthatunk arra, hogy oldalunk szolgáltatásának időtartama megduplázódik. Ha pedig bármilyen fennakadás jelentkezik a távoli végpontnál, a teljes webhely várakozásra kényszerülhet. Ez persze nem jelent komoly gondot felügyeleti vagy kis forgalmú szolgáltatásoknál, de az üzleti, illetve nagy forgalmú webhelyeknél elfogadhatatlan. A megoldás a késleltetés és az elérhetőség akadozásának elkerülésére egy olyan gyorstárstratégia, amely megszünteti a közvetlen függést a távoli szolgáltatástól. Az RPC hívásokhoz könnyen alkalmazható gyorstármódszerekről a 1. és a 11. fejezetben már olvashattunk.XML-RPC
Az XML-RPC minden XML alapú RPC protokoll őse. Alkalmazói leggyakrabban HTTP POST kérelmekbe és válaszokba ágyazzák be, de - mint azt a 15. fejezetben bemutattuk - erre a beágyazásra nincs feltétlenül szükség. Az egyszerű XML-RPC kérelmek olyan XML dokumentumok, melyek az alábbihoz hasonlóan festenek:
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>system.load</methodName>
<params>
</params>
</methodCall>
system.load
), átadva a paramétereket (ez esetben nem adtunk meg egyetlen paramétert sem). Az eredmény végül visszakerül a hívó félhez. Jelen esetben ez a gép aktuális terhelése, melyet a Unix uptime
nevű héjparancsától kaptunk meg. Íme egy lehetséges kimenet:
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value>
<string>0.34</string>
</value>
</param>
</params>
</methodResponse>
Beszéljünk előbb az ügyfél kódjáról. Az ügyfél készít egy kérelem dokumentumot, elküldi a kiszolgálónak, majd értelmezi a kapott választ. Az alábbi kód a korábbiakban látott kérelmet készíti el, és értelmezi az erre kapott választ:
<?php
require_once 'XML/RPC.php';
$client = new XML_RPC_Client('/xmlrpc.php', 'www.example.com');
$msg = new XML_RPC_Message('system.load');
$result = $client->send($msg);
if ($result->faultCode()) {
echo "Error\n";
}
print XML_RPC_decode($result->value());
?>
XML_RPC_Client
objektumot, megadva számára a távoli szolgáltatás URI-jét és címét.Ezután készítünk egy
XML_RPC_Message
objektumot, amely tartalmazza a meghívni kívánt tagfüggvény nevét (system.load
). Mivel a tagfüggvénynek nem adunk meg paramétereket, további adatok átadására nincs szükség.Ezután elküldjük az üzenetet a
send()
tagfüggvénnyel. Az eredményt előbb megvizsgáljuk, és ha nem találunk hibát, az XML formátumból a PHP saját változótípusára alakítjuk az XML_RPC_Decode()
segítségével.Természetesen a kiszolgáló oldalán is szükség van némi kódra, ami fogadja a kérelmet, megtalálja és végrehajtja a megfelelő visszahívható függvényt, majd visszaküldi a választ. Íme egy lehetséges megoldás, amely kezeli az ügyfél kódjában megadott
system.load
tagfüggvényt:
<?php
require_once 'XML/RPC/Server.php';
function system_load()
{
$uptime = `uptime`;
if(preg_match("/load average: ([\d.]+)/", $uptime, $matches)) {
return new XML_RPC_Response(new XML_RPC_Value($matches[1], 'string'));
}
}
$dispatches = array('system.load' => array('function' => 'system_load'));
new XML_RPC_Server($dispatches, 1);
?>
system.load()
tagfüggvény hívása felel meg. Ez a Unix uptime
parancsát hajtja végre, és az eredményből kiolvassa a gép egyperces átlagos terhelését. Ezután a kapott adatot becsomagolja egy XML_RPC_Value
objektumba, majd a visszaküldéshez beburkolja egy XML_RPC_Response
objektumba.Ezután a visszahívható (callback) függvény rákerül egy kiosztási térképre, amely meghatározza, mely függvényekhez rendelje a kiszolgáló az egyes bejövő kérelmeket. A meghívandó függvényekből készítünk egy
$dispatches
tömböt, amely XML-RPC tagfüggvényneveket képez le PHP függvényekre. Végezetül létrehozunk egy XML_RPC_Server
objektumot, és átadjuk neki az előzőleg készített kiosztási tömböt. A második paraméter 1
értéke azt jelzi, hogy a kérelmet azonnal ki kell szolgálni a service()
tagfüggvénnyel (ez egy belső hívás).A
service()
megvizsgálja a HTTP POST nyers adatait, megkeresi az XML-RPC kérelmet, majd a kiosztás alapján elvégzi a függvényhívást. Mivel a tagfüggvény a PHP $HTTP_RAW_POST_DATA
autoglobálisra hivatkozik, semmiképpen sem szabad kikapcsolnunk a php.ini
fájl always_populate_raw_post_data
beállítását. Ha ezek után elhelyezzük a kiszolgálókódot a www.example.com/xmlrpc.php
címen, és egy tetszőleges gépen futtatjuk az ügyfélkódot, az alábbiakat kapjuk vissza:
> php system_load.php
0.34
Egy kiszolgáló felépítése: a MetaWeblog API megvalósítása
Az XML-RPC igazi erőssége, hogy szabványos módot ad a szolgáltatások közti adatcserére. Ez különösen akkor hasznos, ha nem tudjuk ellenőrizni a kérelem útjának mindkét oldalát. Az XML-RPC-vel könnyen módot adhatunk arra, hogy bárki érintkezhessen a szolgáltatással. Jó példát adnak erre a webnaplóküldési API-k.Számos webnaplózó rendszer létezik, és rengeteg olyan eszköz, melyek segítenek a használatukban és a bejegyzések küldésében. Ha nem volnának szabványos eljárások, a széleskörű felhasználhatóság érdekében minden eszköznek támogatnia kellene minden webnaplót, vagy fordítva. Az ilyen kapcsolatrendszer megtartása lehetetlen, ha a benne részt vevő alkalmazások száma növekszik.
Jóllehet a webnaplók lehetőségei és megvalósításai változatosak lehetnek, lehetséges olyan szabványos műveletcsalád meghatározása, melyek a bejegyzések küldését végzik. A webnaplóknak és az eszközöknek ezek után csak a megfelelő felületet kell megvalósítaniuk, és így mindenki mindenkivel együttműködhet.
Dacára a webnaplózó rendszerek nagy számának, mindössze három webnaplóküldési API terjedt el széles körben: a Blogger API, a MetaWeblog API, valamint a MovableType API (ami valójában mindössze a MetaWeblog API bővítése). A bejegyzésküldő eszközök e három protokoll valamelyikét használják az adatátvitelhez, így ha mindegyiküket megvalósítjuk, webnaplónk képes lesz fogadni bármely eszköz bejegyzéseit. Mindez nagyszerű lehetőség arra, hogy egy új webnaplózó rendszert elfogadottá tegyünk.
Természetesen először egy webnaplózó rendszerre van szükség, melyhez ezek az API-k kapcsolódhatnak. Egy teljes webnaplózó rendszer felépítése meghaladná könyvünk kereteit, így hát megelégszünk azzal, hogy egy XML-RPC réteget adunk a Serendipity webnaplóhoz. A szóban forgó API-k a bejegyzések küldését intézik, így a Serendipity alábbi eljárásaival kell érintkezniük:
<?php
function serendipity_updertEntry($entry) {}
function serendipity_fetchEntry($key, $match) {}
?>
serendipity_updertEntry()
frissít egy bejegyzést, vagy beszúr egy újat, attól függően, hogy megadtuk-e számára az id
változó értékét. A $entry
valójában egy tömb, amely az alábbi adatbázistábla egy általános sorának felel meg (vagyis elemei az oszlopokat adják):
CREATE TABLE serendipity_entries (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) DEFAULT NULL,
timestamp INT(10) DEFAULT NULL,
body TEXT,
author VARCHAR(20) DEFAULT NULL,
isdraft INT
);
serendipity_fetchEntry()
kiolvas egy bejegyzést a táblából a megadott kulcs érték pár alapján.A MetaWeblog API több lehetőséget biztosít, mint a Blogger API, így előbbi megvalósítására teszünk kísérletet. Tagfüggvényei közül az alábbi három fontosabbat kell megemlítenünk:
metaWeblog.newPost(blogid,username,password,item_struct,publish) returns string
metaWeblog.editPost(postid,username,password,item_struct,publish) returns true
metaWeblog.getPost(postid,username,password) returns item_struct
blogid
a megcélzott webnapló azonosítója (ami jól jön, ha a rendszer több webnaplót is fenntart), a username
és a password
a küldő azonosítására szolgál, a publish
pedig egy jelző, amely megmondja, hogy a küldött bejegyzés csak vázlat-e, vagy egyenesen mehet a naplóba. Az item_struct
a küldött adatok tömbje.Ahelyett, hogy saját formátumot választott volna az adatbevitelhez, Dave Winer, a MetaWeblog leírásának szerzője az RSS 2.0 leírás
item
elemének meghatározását választotta (ezt megtalálhatjuk a http://blogs.law.harvard.edu/tech/rss címen). Az RSS egy szabványosított XML formátum cikkek és naplóbejegyzések közlésére. Az item
bejegyzése az alábbi elemeket tartalmazza:Elem | Leírás |
---|---|
title | Az item címe. |
link | Az elem formázott alakjához vezető URL. |
description | Az elem összefoglaló leírása |
author | Az elem szerzőjének neve. Az RSS szabványban e-mail címeket kérnek, de gyakrabban használnak beceneveket. |
pubDate | A bejegyzés közzétételének dátuma |
A szabvány emellett lehetővé teszi egyéb mezők használatát is - hivatkozásokat megjegyzésekre, egyértelmű azonosítókat, valamint kategóriákat. Mindemellett számos webnapló kibővíti az RSS szabványt, úgy, hogy az tartalmazza a
content:encoded
elemet is, ami a teljes küldeményt tárolja, nem csak annak összefoglalóját, melyet hagyományosan az RSS description
elemében találhatunk meg.A MetaWeblog API megvalósításához a korábban említett három tagfüggvénnyel kell foglalkoznunk. Először nézzük, hogyan küldhetünk új bejegyzéseket:
<?php
function metaWeblog_newPost($message) {
$username = $message->params[1]->getval();
$password = $message->params[2]->getval();
if(!serendipity_authenticate_author($username, $password)) {
return new XML_RPC_Response('', 4, 'Authentication Failed');
}
$item_struct = $message->params[3]->getval();
$publish = $message->params[4]->getval();
$entry['title'] = $item_struct['title'];
$entry['body'] = $item_struct['description'];
$entry['author'] = $username;
$entry['isdraft'] = ($publish == 0)?'true':'false';
$id = serendipity_updertEntry($entry);
return new XML_RPC_Response( new XML_RPC_Value($id, 'string'));
}
?>
metaWeblog_newPost()
kinyeri a kérelemből a username
és a password
paramétereket, majd kicsomagolja XML alakjukat PHP típusokba a getval()
tagfüggvénnyel. A függvény ezután hitelesíti a megadott felhasználót. Amennyiben ez nem sikerül, visszaküld egy üres XML_RPC_Response
objektumot egy "Authentication Failed" (Sikertelen hitelesítés) hibaüzenettel.Ha a hitelesítés sikeres, a
metaWeblog_Post()
beolvassa az item_struct
paramétert, és a getval()
segítségével kicsomagolja a $item_struct
tömbbe. Ebből elkészíti a Serendipity $entry
paraméterét, melyet átad a serendipity_updertEntry()
tagfüggvényének. Végül a hívó egy XML_RPC_Response
objektumot kap az új bejegyzés azonosítójával.A
MetaWeblog.editPost
háttérkódja igencsak hasonló a MetaWeblog.newPost
tagfüggvénynél látottakhoz:
<?php
function metaWeblog_editPost($message) {
$postid = $message->params[0]->getval();
$username = $message->params[1]->getval();
$password = $message->params[2]->getval();
if(!serendipity_authenticate_author($username, $password)) {
return new XML_RPC_Response('', 4, 'Authentication Failed');
}
$item_struct = $message->params[3]->getval();
$publish = $message->params[4]->getval();
$entry['title'] = $item_struct['title'];
$entry['body'] = $item_struct['description'];
$entry['author'] = $username;
$entry['id'] = $postid;
$entry['isdraft'] = ($publish == 0)?'true':'false';
$id = serendipity_updertEntry($entry);
return new XML_RPC_Response( new XML_RPC_Value($id?true:false, 'boolean'));
}
?>
$entry
tömböt, és elküldjük a naplónak. Ha a serendipity_updertEntry
a $id
értékkel tér vissza, működése sikeres volt, így a válaszban a true
értéket adjuk vissza - ha nem volt sikeres, a válaszunk false
.Utolsóként a
MetaWeblog.getPost
megvalósítását kell elkészítenünk. Ez a serendipity_fetchEntry()
segítségével hozzájut a bejegyzés adataihoz, és ebből egy, az item_struct
adatokat tartalmazó XML választ készít.Lássuk, hogy fest a kód:
<?php
function metaWeblog_getPost($message) {
$postid = $message->params[0]->getval();
$username = $message->params[1]->getval();
$password = $message->params[2]->getval();
if(!serendipity_authenticate_author($username, $password)) {
return new XML_RPC_Response('', 4, 'Authentication Failed');
}
$entry = serendipity_fetchEntry('id', $postid);
$tmp = array(
'pubDate' => new XML_RPC_Value( XML_RPC_iso8601_encode($entry['timestamp']), 'dateTime.iso8601'),
'postid' => new XML_RPC_Value($postid, 'string'),
'author' => new XML_RPC_Value($entry['author'], 'string'),
'description' => new XML_RPC_Value($entry['body'], 'string'),
'title' => new XML_RPC_Value($entry['title'],'string'),
'link' => new XML_RPC_Value(serendipity_url($postid), 'string')
);
$entry = new XML_RPC_Value($tmp, 'struct');
return new XML_RPC_Response($entry);
}
?>
item
adataiból álló tömböt készítünk. Az XML_RPC_iso8601()
elvégzi a Serendipity által használt Unix időbélyegző átalakítását az RSS item
által megkövetelt ISO 8601 szabványúra. A kapott tömb ezután becsomagolva egy XML_RPC_Value [code]struct
-ba kerül. Ez a szabványos módszer arra, hogy XMLRPC struct
típust készítsünk a PHP alaptípusokból. Az eddigiekben láttunk string
, boolean
, dateTime.iso8601
és struct
azonosítókat, melyeket átadhattunk az XML_RPC_Value
objektumnak. Érdemes felsorolnunk az összes lehetőséget:Típus | Lehetőség |
---|---|
i4/int | 32 bites egész |
boolean | Logikai érték |
double | Lebegőpontos szám |
string | Karakterlánc |
dateTime.iso861 | ISO 861 formátumú időbélyegző |
base64 | Base-64 kódolású karakterlánc |
struct | Társításos (asszociatív) tömb |
array | Nem társításos (indexelt) tömb |
A
struct
és az array
típusok bármilyen más típust (köztük további struct
, illetve array
elemeket) tartalmazhatnak. Ha nem adunk meg típust, a rendszer automatikusan a string
mellett dönt. Jóllehet a PHP minden adata leírható a string
, struct
, illetve az array
típusok valamelyikével, más típusok is támogatást kaptak, mivel a más nyelven írt alkalmazásoknak esetleg jobban meghatározott adattípusokra van szükségük.A függvények bejegyzéséhez egy kiosztási tömböt készítünk:
<?php
$dispatches = array(
'metaWeblog.newPost' => array('function' => 'metaWeblog_newPost'),
'metaWeblog.editPost' => array('function' => 'metaWeblog_editPost'),
'metaWeblog.getPost' => array('function' => 'metaWeblog_getPost')
);
$server = new XML_RPC_Server($dispatches,1);
?>
Hurrá! Programunk e pillanattól kezdve megfelel a MetaWeblog API-nak!
Az XML-RPC szolgáltatások automatikus felderítése
Hasznos lehet, ha egy felhasználó valamilyen módon adatokat kérhet a kiszolgálótól az XML-RPC szolgáltatásokra nézve. Erre az XML-RPC három tagfüggvényt is rendelkezésünkre bocsát:- system.listMethods Visszaadja a kiszolgáló által megvalósított összes tagfüggvény nevét (minden visszahívható függvényt, ami szerepel a kiosztási térképen).
- system.methodSignature A tagfüggvény neve alapján megadja a lehetséges prototípusokat.
- system.methodHelp Fogadja a tagfüggvény nevét, és a leírásával tér vissza.
system.methodSignature
által visszaadott adatokat a felhasználónak kell pontosan meghatároznia. Az XML-RPC tagfüggvényeinek változó paraméterei lehetnek, így a visszatérési érték is egy tömb, amely a lehetséges prototípusokat tartalmazza. E prototípusok maguk is tömbök - első elemük a tagfüggvény visszatérési típusa, ezután pedig a paraméterek típusai következnek.E kiegészítő adatok tárolására a kiszolgálónak bővítenie kell kiosztási térképét - ezt láthatjuk a
metaWeblog.newPost
tagfüggvény példáján:
<?php
$dispatches = array(
'metaWeblog.newPost' => array(
'function' => 'metaWeblog_newPost',
'signature' => array(array(
$GLOBALS['XML_RPC_String'],
$GLOBALS['XML_RPC_String'],
$GLOBALS['XML_RPC_String'],
$GLOBALS['XML_RPC_String'],
$GLOBALS['XML_RPC_Struct'],
$GLOBALS['XML_RPC_String']
)),
'docstring' => 'Takes blogid, username, password, item_struct '.
'publish_flag and returns the postid of the new entry'
),
/* ... */
);
?>
<?php
<?php
require_once 'XML/RPC.php';
if($argc != 2) {
print "Must specify a url.\n";
exit;
}
$url = parse_url($argv[1]);
$client = new XML_RPC_Client($url['path'], $url['host']);
$msg = new XML_RPC_Message('system.listMethods');
$result = $client->send($msg);
if ($result->faultCode()) {
echo "Error\n";
}
$methods = XML_RPC_decode($result->value());
foreach($methods as $method) {
$message = new XML_RPC_Message('system.methodSignature', array(new XML_RPC_Value($method)));
$response = $client->send($message)->value();
print "Method $method:\n";
$docstring = XML_RPC_decode( $client->send( new XML_RPC_Message('system.methodHelp', array(new XML_RPC_Value($method)) ) )->value() );
if($docstring) {
print "$docstring\n";
}
else {
print "NO DOCSTRING\n";
}
$response = $client->send($message)->value();
if($response->kindOf() == 'array') {
$signatures = XML_RPC_decode($response);
for($i = 0; $i < count($signatures); $i++) {
$return = array_shift($signatures[$i]);
$params = implode(", ", $signatures[$i]);
print "Signature #$i: $return $method($params)\n";
}
} else {
print "NO SIGNATURE\n";
}
print "\n";
}
?>
> xmlrpc-listmethods.php http://www.example.org/serendipity_xmlrpc.php
/* ... */
Method metaWeblog.newPost:
Takes blogid, username, password, item_struct, publish_flag and returns the postid of the new entry
Signature #0: string metaWeblog.newPost(string, string, string, struct, string)
/* ... */
Method system.listMethods:
This method lists all the methods that the XML-RPC server knows how to dispatch
Signature #0: array system.listMethods(string)
Signature #1: array system.listMethods()
Method system.methodHelp:
Returns help text if defined for the method passed, otherwise returns an empty string
Signature #0: string system.methodHelp(string)
Method system.methodSignature:
Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)
Signature #0: array system.methodSignature(string)
/* ... */
Method metaWeblog.newPost:
Takes blogid, username, password, item_struct, publish_flag and returns the postid of the new entry
Signature #0: string metaWeblog.newPost(string, string, string, struct, string)
/* ... */
Method system.listMethods:
This method lists all the methods that the XML-RPC server knows how to dispatch
Signature #0: array system.listMethods(string)
Signature #1: array system.listMethods()
Method system.methodHelp:
Returns help text if defined for the method passed, otherwise returns an empty string
Signature #0: string system.methodHelp(string)
Method system.methodSignature:
Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)
Signature #0: array system.methodSignature(string)
Vagyis magyarul:
metaWeblog.newPost
tagfüggvény:
Fogadja ablogid
,username
,password
,item_struct
éspublish_flag
paramétereket, majd az új bejegyzés azonosítójával tér vissza.
system.listMethods
tagfüggvény:
Felsorol minden olyan tagfüggvényt, melynek kiosztására az XML-RPC kiszolgáló képes.
system.methodHelp
tagfüggvény:
Az átadott tagfüggvény leírásával tér vissza, vagy ha ez nem létezik, egy üres karakterlánccal.
system.methodSignature
tagfüggvény:
Az átadott tagfüggvény ismert prototípusait (vagyis tömbök egy tömbjét) adja vissza. Ha nincs ismert prototípus, a visszatérési érték egy nulltömb (ezt atype != array
feltétellel vizsgálhatjuk).
Jo kis reklám...
Első bekezdés...
-boogie-
Remélem ezúttal a hozzáér
--
slink
Melyik könyvre gondolsz?
tényleg jó
re: tenyleg jo
Felho
u.i. Az amugy vicces volt, hogy a Hibakezelesrol szolo peldafejezetet kiszolgalo oldal egy java NullPointerException-t dobott csak sokaig a SAMS-nel :)
Nekem ami nagyon tetszett kö
Nagyon sokat segített megérteni, átgondolni és felépíteni azt a rendszert, amit most jó sokan használnak a cégnél.
Megjelent...
Most vettem meg
Elso ranezesre jo lesz. Nem az alapoktol kezdi, ahogy nezem php5-re van kihegyezve. Majd ha tovabb jutottam, majd meg irok rola...
[dt]
Vélemények, kritika jöhet