Hlavní navigace

Webové služby v PHP: XML-RPC a SOAP

Koncept webových služeb umožňuje protokolem HTTP volat funkce na vzdáleném serveru, předávat jim parametry a pracovat s vrácenými výsledky. Je přitom úplně jedno, v jakém programovacím jazyce je webová služba napsaná i z jakého jazyka ji voláme. Rozdíly se smývají ve formátu výměny dat, kterým je obvykle XML.

Tweetni to Odměnte autora  Jak to funguje?

Webové služby lze použít všude tam, kde potřebujeme partnerům předávat nějaká data nebo tato data naopak získávat. Může jít o seznam produktů, aktuální počasí, výsledky vyhledávání, …

Jako protokol pro práci s webovými službami se nejčastěji používá buď jednodušší XML-RPC, nebo komplexnější SOAP. K webové službě v protokolu SOAP lze navíc připojit tzv. WSDL dokument, který popisuje veškerou funkčnost webové služby, a ze kterého tedy můžeme zjistit, jaké funkce s jakými parametry a jakou návratovou hodnotou lze přes tuto webovou službu volat.

Požadavky a odpovědi můžeme zpracovávat stejně jako jakékoliv XML, PHP navíc pro oba nejběžnější druhy služeb nabízí extenze, které nás od přenosového formátu zcela odstíní: XML-RPC a SOAP (v PHP 4 lze použít knihovnu NuSOAP). V tomto článku si ukážeme, jak lze vytvářet požadavky v obou protokolech. Poměrně jednoduše lze na požadavky i odpovídat (vytvořit server), tomu se tento článek ale nevěnuje.

XML-RPC

Extenze XML-RPC pracuje na nižší úrovni a poskytuje pouze základní funkce zakódování požadavku a jeho dekódování. O samotné zavolání se musíme postarat sami:

<?php
/** Položení XML-RPC požadavku
* @param string $url URL webové služby
* @param string $method funkce, která se má zavolat
* @param string $params parametry, které se mají funkci předat
* @param string [$encoding] kódování odpovědi, výchozí je utf-8
* @return mixed data vrácená funkcí
*/
function xmlrpc($url, $method, $params, $encoding = 'utf-8') {
    $context = stream_context_create(array('http' => array(
        'method' => "POST",
        'header' => "Content-Type: text/xml",
        'content' => xmlrpc_encode_request($method, $params, array('encoding' => $encoding))
    )));
    return xmlrpc_decode(file_get_contents($url, false, $context), $encoding);
}
?> 

Funkce předpokládá zapnutou direktivu allow_url_fopen, která dovoluje pracovat se vzdálenými soubory. Pokud je tento požadavek splněn, dá se s XML-RPC pomocí této funkce velice jednoduše pracovat, jinak je potřeba funkci přepsat buď na extenzi CURL nebo na funkci fsockopen.

SOAP

Extenze SOAP umožňuje pracovat na vyšší úrovni a po zaregistrování webové služby už můžeme přímo volat její funkce. Práci s touto extenzí si ukážeme na službě Live Search, která nabízí vyhledávání přes protokol SOAP. Pro použití této služby se musíme zaregistrovat, čímž získáme klíč umožňující položení až 25 000 dotazů denně. Díky připravenému WSDL dokumentu můžeme službu začít ihned používat.

Nejprve zjistíme, jaké funkce můžeme používat. To lze zjistit buď z dokumentace nebo přímo z WSDL dokumentu:

<?php
$soap = new SoapClient('http://soap.search.msn.com/webservices.asmx?wsdl');
print_r($soap->__getFunctions()); // array('SearchResponse Search(Search $parameters)')
?> 

Dozvíme se, že existuje jediná funkce Search s parametrem typu Search a návratovou hodnotou typu SearchResponse. Co jednotlivé typy znamenají, můžeme zjistit zavoláním funkce SoapClient::__get­Types. Dozvíme se, že typ Search je struktura s jediným prvkem Request typu SearchRequest. SearchRequest je zase struktura s prvky jako AppID (náš klíč), Query (dotaz, který pokládáme), CultureInfo (informace o jazyku a místu vyhledávání, hodnota cs-CZ ale bohužel zatím není podporována) nebo Requests (oblast, kterou chceme prohledávat). V PHP se struktury předávají buď jako objekty s odpovídajícími vlastnostmi nebo jednoduše jako asociativní pole:

<?php
define("LIVE_APP_ID", "zaregistrovaný identifikátor aplikace");
$limit = 10;
$site = "php.vrana.cz";
$query = $_GET["query"];

$soap = new SoapClient('http://soap.search.msn.com/webservices.asmx?wsdl');
$SourceRequest = array(
    "Source" => "Web",
    "Offset" => intval($_GET["offset"]),
    "Count" => $limit,
    "ResultFields" => "All",
);
$Search = array(
    "AppID" => LIVE_APP_ID,
    "Query" => "site:$site $query",
    "CultureInfo" => "en-US",
    "SafeSearch" => "Off",
    "Flags" => "None",
    "Requests" => array("SourceRequest" => $SourceRequest),
);
$SearchResponse = $soap->Search(array("Request" => $Search));
?> 

Použití výsledků vyhledávání záleží na naší fantazii – můžeme ho použít pro prohledávání na vlastních stránkách (přidáním operátoru site: přímo do dotazu) nebo třeba pro pravidelné zjišťování pozice našich stránek na vybrané dotazy (to se dá udělat i přímým rozebráním stránky s výsledky, použití webové služby je ale spolehlivější a hlavně v souladu s licencí).

Funkce Search vrátí hlubokou strukturu s výsledky pro jednotlivé zdroje vyhledávání (kromě webu lze prohledávat i reklamy, obrázky, telefonní seznam, opravy překlepů, …). My prohledáváme pouze web, takže s výsledkem můžeme přímo pracovat:

<?php
$SourceResponse = $SearchResponse->Response->Responses->SourceResponse;
if (!$SourceResponse->Results->Result) {
    echo "<p>Nic nebylo nalezeno.</p>\n";
} else {
    echo "<dl>\n";
    foreach ($SourceResponse->Results->Result as $Result) {
        echo '<dt><a href="' . htmlspecialchars($Result->Url) . '">';
        echo htmlspecialchars($Result->Title) . "</a></dt><dd>";
        echo htmlspecialchars($Result->Description) . "</dd>\n";
    }
    echo "</dl>\n";
}
if ($SourceResponse->Total > $_GET["offset"] + $limit) {
    echo "<p><a href='?query=" . urlencode($query) . "&amp;offset=" . ($_GET["offset"] + $limit);
    echo "'>Další</a> z celkem $SourceResponse->Total.</p>\n";
}
?> 

Nalezené výsledky zobrazíme v seznamu, a pokud jich je hodně, zobrazíme odkaz na další stránku.

Závěr

Díky existujícím extenzím se v PHP s webovými službami pracuje velice pohodlně – jsme zcela odstíněni od přenosového formátu a jednoduše voláme funkce a zpracováváme výsledky podobně, jako to děláme s lokálními knihovnami.


Podobně laděné texty můžete najít i na autorově weblogu PHP triky.

Anketa

Který protokol webových služeb preferujete?

       

Jakub Vrána

Jakub Vrána

Autor se živí programováním v PHP, podílí se na jeho oficiální dokumentaci, vyučuje ho na MFF UK a vede odborná školení. Poznámky si zapisuje na weblog PHP triky.

Ohodnoťte jako ve škole:
Průměrná známka 2,92
Tweetni to Odměnte autora  Jak to funguje?

Školení: Mobile - web, aplikace nebo responsivní design?

DW - Školení použitelnosti
  • Proč vůbec řešit uživatele mobilních zařízení.
  • Jak přistupovat k návrhu a správě obsahu pro mobilní digitální produkty.
  • Pochopíte, že mobile je příležitost a ne omezení.

Chcete pro svůj byznys využit mobilní web, responsivní web nebo mobilní aplikaci? Pomůžeme vám se správně rozhodnout!

Další informace o školení Mobile - web, aplikace nebo responsivní design?

       

Přehled názorů

xml-rpc vs. fastrpc
edois 10. 8. 2007 08:30
Nový
└ 
fastrpc je humus - nebrat!
Martin Soukup 10. 8. 2007 10:56
Nový
 
├ 
Re: fastrpc je humus - nebrat!
edois 10. 8. 2007 11:08
Nový
 
│
└ 
Re: fastrpc je humus - nebrat!
mekele 11. 8. 2007 04:10
Nový
 
├ 
Re: fastrpc je humus - nebrat!
edois 10. 8. 2007 11:09
Nový
 
│
└ 
Re: fastrpc je humus - nebrat!
Martin Soukup 10. 8. 2007 11:22
Nový
 
│
 
├ 
Re: fastrpc je humus - nebrat!
edois 10. 8. 2007 11:27
Nový
 
│
 
├ 
Re: fastrpc je humus - nebrat!
llook 10. 8. 2007 11:53
Nový
 
│
 
│
└ 
Re: fastrpc je humus - nebrat!
eee 10. 8. 2007 13:06
Nový
 
│
 
│
 
└ 
Re: fastrpc je humus - nebrat!
llook 11. 8. 2007 12:06
Nový
 
│
 
└ 
Re: fastrpc je humus - nebrat!
Petr Andrš 10. 8. 2007 16:35
Nový
 
│
 
 
└ 
Re: fastrpc je humus - nebrat!
edois 10. 8. 2007 16:41
Nový
 
│
 
 
 
└ 
Re: fastrpc je humus - nebrat!
edois 11. 8. 2007 00:35
Nový
 
├ 
Re: fastrpc je humus - nebrat!
ou007sider 10. 8. 2007 15:09
Nový
 
└ 
Re: fastrpc je humus - nebrat!
ou007sider 10. 8. 2007 15:14
Nový
 
 
└ 
Re: fastrpc je humus - nebrat!
edois 11. 8. 2007 00:37
Nový
REST
Pichi 10. 8. 2007 10:27
Nový
├ 
Re: REST
peter 10. 8. 2007 10:54
Nový
├ 
Re: REST
edois 10. 8. 2007 10:55
Nový
│
└ 
Re: REST
Pichi 10. 8. 2007 11:28
Nový
│
 
└ 
Re: REST
edois 10. 8. 2007 11:35
Nový
│
 
 
└ 
Re: REST
Pichi 10. 8. 2007 13:19
Nový
│
 
 
 
└ 
Re: REST
edois 10. 8. 2007 13:34
Nový
│
 
 
 
 
└ 
Re: REST
peter 10. 8. 2007 14:37
Nový
│
 
 
 
 
 
└ 
Re: REST
edois 10. 8. 2007 15:57
Nový
│
 
 
 
 
 
 
├ 
Re: REST
beer 10. 8. 2007 17:16
Nový
│
 
 
 
 
 
 
├ 
Re: REST
beer 10. 8. 2007 17:27
Nový
│
 
 
 
 
 
 
│
└ 
Re: REST
edois 10. 8. 2007 18:54
Nový
│
 
 
 
 
 
 
└ 
Re: REST
Pichi 14. 8. 2007 20:53
Nový
│
 
 
 
 
 
 
 
└ 
Re: REST - hele Pichusi, a co je to REST
AntiPichos 15. 8. 2007 07:52
Nový
└ 
Re: REST
edois 11. 8. 2007 00:56
Nový
SOAP vs nuSOAP
Tom 10. 8. 2007 23:59
Nový
└ 
Re: SOAP vs nuSOAP
edois 11. 8. 2007 00:30
Nový
Live.com
freshmouse 11. 8. 2007 12:29
Nový
Nefunguje __getFunctions()
Radas 16. 8. 2007 21:42
Nový
nefukčni
Martin 18. 2. 2009 23:00
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem