Izbornik Zatvoriti

PHP, nusoap i veb servis za kursnu listu NBS

Skraćena veza: https://pedja.supurovic.net/veza/4685

Pre nekoliko dana sam krenuo da uradim rutinu za preuzimanje kursne liste sa sajta Narodne Banke Srbije. Na prvi pogled, s obzirom da su ponudili javni veb servis u SOAP tehnologiji, izgledalo je da će stvar biti urađena rutinski. Nažalost nije. Pošteno sam se namučio da sve namestim.

Dokumentacija koja je ponuđena na sajtu NBS je prilično štura i nije baš od velike pomoći, naročito nekome ko se prvi put upušta u ovakvu stvar. I Gugl o celoj ovoj stvari malo zna, te uglavnom prikazuje linkove na pomenutu dokumentaciju ali i na nekoliko sajtova gde ljudi traže pomoć pokušavajući da se izbore sa korišćenjem servisa i bez vidnih rešenja.

Stoga, s obzirom da mi je najzad uspelo da izvedem povezivanje, evo uputstva kako se iz PHP-a koristi veb servis NBS za pristup kursnim listama.

Kako početi

Najpre, da biste koristili veb servise NBS morate biti registrovani korisnik. Detaljno objašnjenje kako se to čini imate na sajtu NBS , a ukratko, treba da pošaljete popunjen i overen zahtev za učlanjenje u sistem veb-servisa NBS. Procedura je jednostavna i završava se za nekoliko dana, s obzirom da zahtev morate, pored imejla, poslati i običnom poštom, odštampan.

Kada postanete član, dobićete šifru licence koja vam je neophodna da biste servis mogli koristiti. Pored ove šifre, potrebni su vam i korisničko ime i lozinka a njih sami određujete i navodite u zahtevu za učlanjenje.

Nakon što postanete član moći ćete odmah koristiti sve besplatne veb servise NBS. Među njima je i servis za pristup kursnim listama koji nas interesuje. Ako vas interensuju servisi koji se naplaćuju njih posebno morate aktivirati.

Šta je SOAP?

Za detaljan odgovor na ovo pitanje poslaću vas na Gugl. Stvar je suviše složena da nema svrhe da vam prepričavam obilje dokumentacije koja je dostupna. Daču vam vrlo kratko i uopšteno objašnjenje.

Internet je omogućio da se funkcionalnost aplikacija proširi van jednog računara i van lokalne mreže – na ceo Internet. To znači da je moguće na jednom računaru pokrenuti aplikaciju, a ona će koristiti podatke sa neke druge lokacije koja može biti bilo gde, samo je važno da server sa podacima bude dostupan preko Interneta. Nešto složeniji pristup omogućava da se i sama aplikacija nalazi na Internetu, a da korisnik ima samo jednostavan klijent na svom računaru.

Najočigledniji primer takvog pristupa je veb čitač kojim upravo čitate ovaj članak. To je jednostavna aplikacija koja, sama za sebe nema neku svrhu, ali kada otvorite neki sajt vi u stvari učitavate program koji veb čitaču daje funkcionalnost. Za neke druge namene koriste se drugačiji klijenti i drugačiji serveri koji omogućuju i veoma složene aplikacije.

Sa tim, pojavila se i neizbežna potreba da seomogući da raznorodni računari, operativni sistemi i programi mogu međusobno ne samo da komuniciraju nego i da izvršavaju aplikacije. Pojavili su se protokoli koji su upravo to omogućili. Oni omogućuju da sa klijenta izvršite programske procedure na serveru. Te procedure mogu jednostavno da vam daju tražene podatke ali mogu i da izvrše obradu podataka na serveru. SOAP (Simple Object Access Protocol) je jedan od takvih protokola.

Pogodnost SOAP-a je u tome što je on univerzalan i prevazilazi razlike između hardvera, operativnih sistema, programskih jezika kao i samih aplikacija. SOAP aplikacija može da se izvršava na bilo čemu, počev od običnog računara, preko PDA, mobilnog telefona kao i na svakom drugom uređaju koji može da sa SOAP serverom komunicira preko Interneta.

Naravno, ne izvršava se stvarno se SOAP aplikacija na svim ovim uređajima već oni mogu, korišćenjem SOAP protokola, da pokreću procedure koje se izvršavaju na serveru i da dobiju od njega podatke koje dalje mogu da koriste.

Tako široka kompatibilnost SOAP protokola se zasniva na tome što on svu komunikaciju između klijenata i servera zasniva na XML porukama. SOAP poruke su, u stvari, samo XML poruke sa unapred jasno definisanom strukturom.

Nije zato iznenađujuće zašto se Narodna banka Srbije odlučila da ovaj protokol koristi za obezbeđenje svog javnog veb servisa: time su omogućili da podatke sa njihovog servera možete dobiti na bilo kom uređaju i iz bilo kog okruženja koje ima pristup Internetu.

Kako funkcioniše veb sevis NBS

Da biste mogli da dobijete neku informaciju od veb servisa NBS potrebni su vam sledeći podaci:

– korisničko ime (UserName)

– lozinka za pristup (Password)

– šifra licence (LicenceID)

– lokacija WSDL defincije servisa

– naziv imenskog prostora (NameSpace)

– naziv metoda (programske funkcije) servisa

– parametri koji se prosleđuju izabranoj metodi

Nije neophodno da ručno kreirate XML poruke da biste koristli veb servis. Postoje gotove biblioteke koje to mogu uraditi umesto vas, na osnovu parametara koje im prosledite.

Prilikom uspostavljanja konekcije sa veb servisom neophodno je da se identifikujete. Za to služi zaglavlje za autentifikaciju (AuthenticationHeader) koje se šalje prilikom uspostavljanja konekcije. Ono je specifično za veb servis NBS tako da ga morate pripremiti ručno. Zaglavlje za autentifikaciju se umeće u zaglavlje SOAP poruke i treba da izgleda ovako:

<AuthenticationHeader  xmlns="http://communicationoffice.nbs.rs">
<UserName>korsinicko_ime</UserName>
<Password>lozinka</Password>
<LicenceID>sifra_licence</LicenceID>
</AuthenticationHeader>

Veb servis NBS koristi nekoliko WSDL servisa, pa tako morate izabrati odgovarajuću definiciju zavisno opd toga kakve podatke želite. Potpun spisak svih servisa naći ćete na sajtu NBS. Nas, za preuzimanje kursne liste interesuje Servis za pristup kursnim listama .

Za svaki servis NBS postoje dva tipa: jedan vraća podatke u XML obliku a drugi kao DataSet. Koristićemo XML, tako da je lokacija WSDL defincije servisa koji ćemo koristiti https://webservices.nbs.rs/CommunicationOfficeService1_0/ExchangeRateXmlService.asmx?WSDL.

Imenski prostor (NameSpace) za sve veb servise NBS je isti: http://communicationoffice.nbs.rs.

Spisku metoda veb servisa ExchangeRateXmlService je podugačak, a nas interesuje metod GetExchangeRateByDate , koji daje podatke o kursnoj listi na zadati dan. Ovaj metod ima dva parametra: date datumskog tipa i exchangeRateListTypeID koji je numerički identifikator kursne liste.

Datumski podaci se prosleđuju kao tekstualni u formatu GGGGMMDD (godina sa četiri cifre, mesec sa dve cifre i dan sa dve cifre, sve spojeno).

Identifikator kursne liste je broj. Može imati tri vrednosti: 1 – za devize, 2 – za efektivu i 3 – srednji kurs. Mi ćemo tražiti srednji kurs.

To su svi podaci potrebni da možemo da preuzmemo podatke od veb servisa NBS.

Kako koristiti SOAP u PHP-u

Iako u principu SOAP upite možemo da izvršavamo ručno, jer se u suštini radi o slanju XML poruka, ipak je mnogo bolje to raditi nekom namenskom bibliotekom koja sadrži potpunu implementaciju SOAP protokola. Ja sam izabrao biblioteku nusoap . Ona ima svu potrebnu funkcionalniost i vrlo se jednostavno koristi.

Instalacija biblioteke je jednostavna: preuzmete arhivu i raspakujete je je u direktorijumu gde će se nalaziti PHP program koji treba da je koristi. Dobićete dva nova poddirektorijuma: lib i samples. Prvi sadrži biblioteku, a drugi možete i da obrišete jer sadrži primere korišćenja biblioteke. Ako vam je potrebno, a trebalo bi da jeste, sa sajta biblioteke možete posebno preuzeti arhivu sa dokumentacijom.

Biblioteku u svoj kod uključujete komandom

require_once('lib/nusoap.php');

SOAP konekciju podešavate kreiranjem objekta iz klase nusoap_client, na primer komandom:

$soap_client = new nusoap_client($soap_wsdl, true);

U bilo kom trenutku možete proveriti stanje objekta klijenta uvidom u brojne metode i svojstva klase nusoap_client. Sve odjednom ih možete pogledati komandom:

print_r ($soap_client);

To će vam svakako trebati ako budete naišli na probleme. Naročito obratite pažnju na metod $soap_client->getError(). Ako ova funkcija vrati bilo kakvu vrednost, to znači da je došlo do neke greške. Ako je greškausledila nakon poziva nekog metoda, onda će ta metoda da vam umesto traženih podataka vrati niz koji opisuje grešku koju je prijavio SOAP server.

Ako imate problema sa pozivom nekog SOAP metoda, dobroje da proverite kako izgleda SOAP poruka koja je poslata serveru. Ona se nalazi u svojstvu $soap_client->request.

Za ostalo, proučite dokumentaciju biblioteke nusoap.

A sad na posao

Posle malo dužeg uvoda možemo da krenemo sa komunikacijom sa SOAP serverom NBS. Pokazaću jednostavan primer koji preuzima kursnu listu na zadati datum po srednjem kursu.

Na početku, moramo uključiti nusoap biblioteku

<?php
require_once('lib/nusoap.php');

a zatim podesiti parametre željene kursne liste

$m_date = '20100811'; // zeljeni datum kursne liste u formatu YYYYMMDD
$m_list_type = 3;     // zelimo kursnu listu posrednjem kursu

Sada podešavamo podatke vezane za registraciju na veb servisu. Ovde morate upisati svoje podatke.

$login_username = 'USERNAME'';
$login_password = 'PASSWORD'';
$login_licenceid = 'LICENCEID';

I preostalo nam je još da podesimo lokaciju WDSL i NameSpace servisa:

$soap_wsdl = "https://webservices.nbs.rs/
CommunicationOfficeService1_0/ExchangeRateXmlService.asmx?WSDL";
$soap_namespace = "http://communicationoffice.nbs.rs";

Krećemo na posao. Prvo kreiramo objekat SOAP klijenta

$soap_client = new nusoap_client($soap_wsdl, true);

i odmah isključimo dekodiranje utf8 znakova, jer veb servisi NBS vraćaju podatke u utf8 formatu a takvi nam i trebaju. Ako ovo ne isključimo sva ćirilična i naša latinična slova bi bila uništena.

$soap_client->decode_utf8 = 0;

Pripremićemo zaglavlje za autentifikaciju, kao što je ranije objašnjeno. To zaglavlje umećemo u zaglavlje SOAP poruke.

$m_header =
'<AuthenticationHeader xmlns="' . $soap_namespace . '">
<UserName>' . $login_username . '</UserName>
<Password>' . $login_password . '</Password>
<LicenceID>' . $login_licenceid . '</LicenceID>
</AuthenticationHeader>';

$soap_client->setHeaders($m_header);

Pripremićemo i parametre koje ćemo proslediti prilikom poziva SOAP metoda. Parametri se prosleđuju u obliku asocijativnog niza.

$p_parameters = array('date'=>$m_date,
                      'exchangeRateListTypeID' => $m_list_type);

Sve je spremno i možemo izvršiti SOAP metod GetExchangeRateByDate sa pripremljenim parametrima.

$m_soap_result = $soap_client->call ('GetExchangeRateByDate',
                                      $p_parameters);

Nakon izvršenog metoda, u $m_soap_result će se nalaziti ili podaci koje smo tražili (u XML obliku) ili poruka o grešci koju je vratio SOAP server. Da li je došlo do greške proveričemo pozivom metoda getError().

Ako nema greške, podaci se nalaze u promenljivoj  $m_soap_result koja je u stvari niz sa jednim elementom pod imenom GetExchangeRateByDateResult.

$m_error = $soap_client->getError();
if ($m_error) {
   //doslo je do greske, ispisacemo dostupne podatke o tome
   echo '<h1>Error:</h1>';
   echo '<pre>';
   print_r ($m_soap_result);
   print_r ($soap_client);
   echo '</pre>';
} else {
   //nema greske, prikazacemo podatke koje smo dobili
   $m_output = $m_soap_result;
   print_r ($m_output);
}
?>

I tu je kraj

Pretpostavljam da ste do ovog mog članka došli nakon što ste i sami naišli na problem i da vam se sada čini da je ovo sve veoma jednostavno. Verujem da se tako činilo i ljudima u NBS pa nisu smatrali za shodno da napišu malo jasniju dokumentaciju. Nadam se da sam na ovaj način upotpunio prazan prostor koji je postojao te da će drugima sada bitilakše da u svoje programe ugrade podršku za veb sevise Narodne banke Srbije.

Ovi servisi nude još mnogo podataka. Ukoliko su vam neki od njih potrebni, proučite dokumentaciju SOAP metoda koji daje to što vam treba i upotrebite ga na sličan način kao u ovom primeru.

Na kraju, evo i datoteke sa kodom koji je korišćen u članku: kursna-lista-nbs-nusoap.zip (5110 downloads )

31 Comments

  1. SadClown

    Videh danas kad si pitao za pomoć na twitteru. Mi smo na faksu pre par godina baš radili soap na primeru NBS web-servisa, i baš smo nusoap koristili. Htedoh da ti pošaljem te primere, ali izgleda da više nemam pristup našem eLearning sistemu :/

    Interesantno je to kako gotovo nigde nisam naišao (osim u NBS) da se koristi soap, svuda koriste API-je zasnovane na REST web-servisima (pa i na FB-u i na twitteru)… (iako načelno ni jedan od njih nije bolji od onog drugog, samo imaju drugačiji pristup problemu). A opet, kao za inat, kod nas (barem na mom faksu) je iz više predmeta obrađivan soap, a o rest-u niko ni reč da bekne. Kod nas večito sve napako xD

  2. Peđa

    Našao sam par primera od ranije ali je NBS promenila API za svoj SOAP tako da oni više ne rade.

    S obzirom koliko ima sajtova koji prikazuju kursneliste koje preuzimaju od NBS, jasno jeda su to ljudi rešili, ali da niko nije preman da drugima pokaže kako, a ako se neko nije ovim bavio ranije, prilično mu je teško da provali sve detalje.

    Zašro su koristili SOAP ne znam. Verovatno je taj ko je progrmairao servis to već znao ili je ghteo da nauči i isproba. Ovo što NBS nudi je moglo da se napravi i na mnogo jednostavniji način. SOAP je samo nepotrebna komplikacija.

  3. Goran

    SOAP je starija i ozbiljnija tehnologija, za ralziku od REST-a poznaje strogo tipizirane podatke. Amazon i eBay su dugo koristili SOAP, mislim da ga još uvek podržavaju. Zgodno je što postoji WSDL, u to vreme očekivalo se da će postojati automatski alati koji generišu klijente zavisno od WSDL opisa servisa.

  4. Goran

    A zašto SOAP, verovatno NBS koristi neki IBM softver koji ume podrazumevano da priča SOAP pa im je to bilo najlakše da ponude i objedine sve veb servise u isti interfejs.

  5. Aleksandar

    Ja nisam uspeo nikada da se registrujem kod njih.
    Dobijam runtime error?
    Mozda zato sto koristim linuks???

    Ranije mi je radilo sa test nalogom, sada mi je potrebna registracija, ali nece…

  6. Pedja R.

    Hvala za skriptu,uspeo sam da se konektujem i izvucem povratan odgovor i zamolio bih Vas za neki tip kako da iz dobijenog niza izvucem samo vrednost evra.Hvala

  7. Pedja R.

    Kad imam xml fajl onda se snalazim sa parsovanjem,ali ovde me buni sto (ako sam dobro ukapirao)xml se nalazi u okviru varijable $m_output…ili sam ja malo vise zalutao???
    Hvala

  8. Alex

    Hvala Vam MNOGO na svemu, gotovo sigurno nikada ne bih uspeo da niste pomogli.
    Imam samo jedan problem.
    Koristim „GetCurrentExchangeRate“ a ne „GetExchangeRateByDate“.
    Kada pustim stranicu, ne prijavljuje ni jednu grešku ali mi ne čita kao da je XML, tačnije ovako izgleda:
    http://img220.imageshack.us/img220/6507/blia.jpg
    (Na sliku je stavljen BLUR efekat)
    Sada ne znam da li tako i treba da izgleda i da li će tako čitati ili ne? Kada odem na CTRL+U (na toj stranici) sve izgleda lepo.
    I da li možda znate neki gotov ili polu gotov PHP kod gde bih mogao da namestim koje valute da se prikazuje i to sve lepo složeno u neku tabelu ili ću morati da se namučim da to napravim sam?

    • Peđa

      Dao sam rešenje za glavni deo posla.

      Ako nećeš sam da se pomučiš, uvek možeš da poručiš od nekoga da ti napravi to što ti treba, na primer od mene.

  9. JP

    vidim da je tema odavno, ali meni je sad aktuelna…moje pitanje je sta ako ne zelim da prosledim drugi parametar (Identifikator kursne liste), u opisu stoji da je samo datum obavezan, medjutim ako drugi parametar postavim na null dobijam
    Error:

    Array
    (
    [faultcode] => soap:Client
    [faultstring] => Server was unable to read request. —> There is an error in XML document (5, 171). —> Input string was not in a correct format.
    [detail] =>
    )

    unapred hvala na odgovoru :)

    • Peđa

      Mislim da je greška u dokumentaciji da je samo date parametar naveden kao obavezan, pošto nema logike da nije obavezan i parametar za tip liste.

      Probaj da umesto null pošalješ prazan string.

  10. JP

    Probala, ponovo javlja gresku :(
    Ja u stvari pokusavam da pozovem metodu
    GetDebtor servisa DebtorXmlService (registar duznika u prinudnoj naplati), za koju ni jedan parametar nije obavezan, ali ako bilo koji postavim na null ili prazan string dobijem gresku Input string was not in a correct format
    U ovom slucaju zaista ima smisla da parametri nisu obavezni, htela sam pretragu samo po maticnom broju, ali nikako ne uspevam da to izvedem :(
    Svaka sugestija je dobrodosla :)

    • Peđa

      To se i meni dešavalo sa nekim drugim funkcijama i posle mnogo porvedenih sati, samo sam mogao da priznam kapitujaciju i odustanem.

      Nažalost, dokumentacija za servis NBS je da budemo učtivi veoma slaba a oni ne pokazuju ama baš nikakav interes da je unaprede. Svaki pokušaj da se od njih dobiju neka dodatna objašnjenja odbijaju u startu.

      Čak su odbili da i ovaj moj članak stave na sajt kao uputstvo za svoje korisnike. Može im se, na državnim su jaslama.

  11. JP

    ako si ti odustao ja mogu samo da sednem i placem :((
    Hvala u svakom slucaju, malo mi je lakse kad vidim da nisam jedina koja ne ume da resi ovo
    Pozdrav :)

  12. Slavko

    Pozdrav.

    Da li ova nusoap biblioteka ima realizovanu konverziju Lista iz C# u nizove u PHP-u.
    Ja imam jedan wsdl koji je uradjen kao wcf servis u .NET i gotovo svaka metoda mi vraca Liste koje treba da prikazem u PHP klijentu. Da li je neko radio slicno nesto ili jos bolje ima volju da malo pomogne. Hvala unapred.

Ostavite odgovor na Peđa Odustani od odgovora

Vaša adresa e-pošte neće biti objavljena. Neophodna polja su označena *

Popunite izraz tako da bude tačan: *

Ovo veb mesto koristi Akismet kako bi smanjilo nepoželjne. Saznajte kako se vaši komentari obrađuju.