Iako sam do sada radio isključivo s REST API-jem koristeći JSON u ovom ću blog postu pokazati kako pomoću SOAP protokola slati/primati XML u PHP-u.
Nekoliko stvari će biti pojašnjeno:
– kako treba izgledati XML kojeg šaljem kako bi dobio očekivani rezultat
– kako raspakirati dobiveni rezultat i od njega napraviti niz (array) podataka
– od čega se sastoji __doRequest metoda
XAMPP
S obzirom da ću sve raditi i testirati na lokalnom računalu potreban mi je XAMPP, jedno od popularnijih PHP razvojnih okruženja.
Ako lokalno želim koristiti SOAP protokol moram aktivirati SoapClient jer ću inače dobiti sljedeću grešku:
|
1 |
Fatal error: Uncaught Error: Class 'SoapClient' not found in C:\xampp\htdocs\soap\demo.php:57 Stack trace: #0 {main} thrown in C:\xampp\htdocs\soap\demo.php on line 57 |
Aktivacija se vrši unutar Apache modula – Config – PHP (php.ini).
Potrebno je pronaći ;extension=php_soap.dll i maknuti ; te nakon toga restartati Apache modul.
Postman
Prije nego krenem s izradom primjera u PHP-u moram se uvjeriti da API radi, a to ću napraviti kroz Postman.
Kod slanja zahtjeva na API moram pod Headers postaviti Content-Type: text/xml dok u Body ide XML u raw obliku.
Na prvom API-ju dobijem popis stanica.
|
1 |
http://example.com:9909/demoSoap.asmx?op=getStanice |
Na drugom API-ju, nakon što pošaljem ID dvije stanice i datum, dobijem popis aktivnih stanica za odabrani datum.
|
1 |
http://example.com:9909/demoSoap.asmx?op=getLinije |
PHP demo aplikacija
U službenoj dokumentaciji na adresi https://www.php.net/manual/en/class.soapclient.php saznao sam koje parametre trebam poslati kako bi dobio željeni rezultat.
__doRequest metoda me u ovom slučaju najviše zanima.
|
1 |
public SoapClient::__doRequest ( string $request , string $location , string $action , int $version [, int $one_way = 0 ] ) : string |
Iz priložene dokumentacije vidim da mi je potrebno četiri tj. pet parametara.
getStanice
string $request je zapravo XML koji sam u Postmanu slao kroz Body.
|
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getStanice xmlns="http://www.tomislavstankovic.com/"> <Korisnik>string</Korisnik> <Lozinka>string</Lozinka> </getStanice> </soap:Body> </soap:Envelope> |
string $location je URL API-ja.
|
1 |
http://example.com:9909/demoSoap.asmx?op=getStanice |
string $action je potrebno pronaći u dokumentaciji API-ja.
|
1 2 3 4 5 |
POST /demoSoap.asmx HTTP/1.1 Host: tomislavstankovic.com Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://www.tomislavstankovic.com/getStanice" |
int $version označava verziju XML-a. U ovom slučaju to je 1.
Sve zajedno to izgleda ovako
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php $xmlrequest = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getStanice xmlns="http://www.tomislavstankovic.com/"> <Korisnik>string</Korisnik> <Lozinka>string</Lozinka> </getStanice> </soap:Body> </soap:Envelope>'; $location_URL = 'http://example.com:9909/demoSoap.asmx?op=getStanice'; $client = new SoapClient(null, array( 'method' => 'POST', 'location' => $location_URL, 'Content-Type' => 'Content-type: text/xml', 'uri' => "http://example.com:9909/demoSoap.asmx", )); $result = $client->__doRequest($xmlrequest, $location_URL, "http://www.tomislavstankovic.com/getStanice", 1); ?> |
Nakon što sam dobio rezultat $result trebam iz njega izvući nazive stanica tj. njihove ID-eve kako bi mogao kreirati select polja. Ovdje koristim getElementsByTagName() metodu.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
... $dom = new DOMDocument($result); $dom->loadXML($result); foreach ($dom->getElementsByTagName('NewDataSet') as $sveStanice) { foreach ($sveLinije->getElementsByTagName('stanica') as $stanica) { //$popisStanica[] = $stanica; $popisStanica[] = $stanica->childNodes[1]->nodeValue; $popisStanica[]=$stanica->firstChild->nodeValue; } print_r($popisStanica); } ?> |
print_r($popisStanica); daje sljedeći rezultat u kojemu gledam [nodeValue] unutar kojega se nalazi string sa svim podacima od pojedine stanice. Npr. [nodeValue] => idNAZIVgps1GPS2granicaZEMLJAIDnazivzemljeOZNAKA.
Od toga sada mogu kreirati dva select polja + polje za odabir datuma.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
... <form name="register" method="post"> Početna stanica: <select name="pocetnaStanica"> <?php foreach($popisStanica as $key=> $pocetnaNaziv) { $id=$popisStanicaId[$key]; echo "<option value='$id'>".$pocetnaNaziv."</option>"; } ?> </select> Završna stanica: <select name="zavrsnaStanica"> <?php foreach($popisStanica as $key=> $zavrsnaNaziv) { $id=$popisStanicaId[$key]; echo "<option value='$id'>".$zavrsnaNaziv."</option>"; } ?> </select> Datum: <input type="date" name="datum"> <input type="submit" name="submit" value="Pošalji"/> </form> ?> |
Krajnji rezultat su dva padajuća izbornika sa popisom stanica.
getLinije
string $request je zapravo XML koji sam u Postmanu slao kroz Body.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getLinije xmlns="http://tomislavstankovic.com/"> <Korisnik>string</Korisnik> <Lozinka>string</Lozinka> <StanicaOd>int</StanicaOd> <StanicaDo>int</StanicaDo> <Datum>dateTime</Datum> </getLinije> </soap:Body> </soap:Envelope> |
Parametre StanicaOd, StanicaDo i Datum dohvaćam dinamički putem forme kroz funkciju display().
|
1 2 3 4 5 6 7 |
<?php if(isset($_POST['submit']) && isset($_POST['pocetnaStanica']) && isset($_POST['zavrsnaStanica']) && isset($_POST['datum'])){ display($_POST['pocetnaStanica'],$_POST['zavrsnaStanica'],$_POST['datum']); } else { echo "Odaberite vrijednosti!"; } ?> |
string $location je URL API-ja.
|
1 |
http://example.com:9909/demoSoap.asmx?op=getLinije |
string $action je potrebno pronaći u dokumentaciji API-ja.
|
1 2 3 4 5 |
POST /demoSoap.asmx HTTP/1.1 Host: tomislavstankovic.com Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://www.tomislavstankovic.com/getLinije" |
int $version označava verziju XML-a. U ovom slučaju to je 1.
Sve zajedno to izgleda ovako
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php function display($pocetnaStanica,$zavrsnaStanica,$datum) { $xmlrequest1 = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getLinije xmlns="http://www.tomislavstankovic.com/"> <Korisnik>string</Korisnik> <Lozinka>string</Lozinka> <StanicaOd>'.$pocetnaStanica.'</StanicaOd> <StanicaDo>'.$zavrsnaStanica.'</StanicaDo> <Datum>'.$datum.'</Datum> </getLinije> </soap:Body> </soap:Envelope>'; $location_URL1 = 'http://example.com:9909/demoSoap.asmx?op=getLinije'; $client1 = new SoapClient(null, array( 'method' => 'POST', 'location' => $location_URL1, 'Content-Type' => 'Content-type: text/xml', 'uri' => "http://example.com:9909/demoSoap.asmx" )); $result1 = $client1->__doRequest($xmlrequest1, $location_URL1, "http://www.tomislavstankovic.com/getLinije", 1); } |
Nakon što sam dobio rezultat $result trebam iz njega izvući nazive stanica tj. njihove ID-eve, termine polaska, dolaska i ukupno trajanje putovanja kako bi mogao kreirati tablicu. Ovdje također koristim getElementsByTagName() metodu.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
... <table class="table table-hover table-bordered thead-dark"> <thead class="thead-dark"> <tr> <th>Linija</th> </tr> </thead> <?php try { $result1 = $client1->__doRequest($xmlrequest1, $location_URL1, "http://www.tomislavstankovic.com/getLinije", 1); $dom1 = new DOMDocument($result1); $dom1->loadXML($result1); foreach ($dom1->getElementsByTagName('NewDataSet') as $sveLinije1) { foreach ($sveLinije1->getElementsByTagName('linija') as $linija) { //$naziviLinija[] = $linije1; $naziviLinija[] = $linija->childNodes[2]->nodeValue; //$vrijemePolaska[] = $linija->childNodes[3]->nodeValue; //$vrijemeDolaska[] = $linija->childNodes[4]->nodeValue; //$ukupnoTrajanje[] = $linija->childNodes[5]->nodeValue; } print_r($naziviLinija); foreach($naziviLinija as $nazivLinije => $value) { ?> <tr> <td><?php echo $naziviLinija[$nazivLinije]; ?></td> </tr> <?php } } } catch (SoapFault $exception){ var_dump($exception); } } ?> |
Krajnji rezultat izgleda ovako:
Prikaz vremena polaska, dolaska i trajanje mogu se pomoću jedne funkcije ljepše formatirati.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
function vrativrijeme($vrijemestring) { $x=strpos($vrijemestring,"H"); if ($x==3) { $str2=substr ( $vrijemestring , $x-1, 1); } else if (!$x) { $str2=""; } else { $str2=substr ( $vrijemestring , $x-2, 2); } $str3 = substr($vrijemestring, -3); $y=substr($str3,0,1); if ($y=='H') { $str3=substr($str3,1,1); } else if (!$y){ $str3=""; } else { $str3=substr($str3,0,2); } if (!$x) { $rezultat=$str3; return $rezultat; } else { $rezultat= $str2.":".$str3; return $rezultat; } } ... foreach ($sveLinije1->getElementsByTagName('linija') as $linije1) { $popisLinija1[] = $linije1->childNodes[2]->nodeValue; $polazak[] = vrativrijeme($linije1->childNodes[3]->nodeValue); $dolazak[] = vrativrijeme($linije1->childNodes[4]->nodeValue); $trajanje[] = vrativrijeme($linije1->childNodes[5]->nodeValue); } |
Krajnji rezultat sada izgleda ovako:
Zaključak
Cilj ovog blog posta bio je pokazati kako napraviti demo PHP aplikaciju pomoću koje se može primiti/poslati XML putem SOAP protokola.




![[nodeValue]](https://www.tomislavstankovic.com/blog/wp-content/uploads/2019/05/soap-xml-php-xampp-4-min.png)

![[nodeValue]](https://www.tomislavstankovic.com/blog/wp-content/uploads/2019/05/soap-xml-php-xampp-5-min.png)

