I Web service sono strumenti che permettono di scambiare messaggi fra client e server in una rete distribuita, indipendentemente dal linguaggio di programmazione utilizzato. I più diffusi linguaggi per la programmazione web mettono a disposizioni classi e funzioni per la loro implementazione che avviene utilizzando il protocollo SOAP (Simple Object Access Protocol).
Normalmente l’esposizione delle funzioni server avviene attraverso un documento XML che si chiama WSDL (Web Services Description Language). Secondo quanto descritto nel WSDL associato al servizio è possibile interrogare il server attraverso richieste incapsulate in un documento XML e fatte viaggiare attraverso il protocollo HTTP mediante una richiesta di tipo POST.
Quello che ci interessa ora è di poter inviare una richiesta ad un qualsiasi web service SOAP tramite un documento XML preformattato con i valori richiesti dal server. Possiamo utilizzare la libreria cURL che oggi è inclusa nel pacchetto PHP e ci fornisce le funzioni necessarie ad inviare tramite http una richiesta di tipo POST.
Le proprietà pubbliche sono:
$charset | Il tipo di charset, default: utf-8 |
$connecttimeout | Opzione cURL Connection time out, default: 10 |
$contentType | Header Content-type default: text/xml |
$debug | Abilita cURL debug, default: false |
$md5_pass | Abilita MD5 per la password, default: false |
$post | Opzione cURL Post, default: true |
$returntransfer | Opzione cURL Return transfer, default: true |
$ssl_verifyhost | Opzione cURL SSL Verify Host, default: true |
$ssl_verifypeer | Opzione cURL SSL Verify Peer, default: true |
$timeout | Opzione cURL Time out, default: 10 |
e i metodi pubblici sono:
__construct($url) | Costruttore, input la url per connettersi al Web service |
printExtraHeaders() | Stampa gli headers aggiuntivi |
resetExtraHeaders() | Rimuove tutti gli headers aggiuntivi |
sendXML($post_string) | Invia al web service, input la stringa XML |
setCredentials($user, $pass) | Imposta la username e la password (opzionale), input username e password |
setExtraHeader($extraHeader) | Aggiunge un header, input: stringa con header aggiuntivo |
setExtraHeaders($extraHeaders) | Aggiunge una serie di header, input: header aggintivi in array |
Ecco il codice della classe:
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | <?php /** * SendXMLToWebService * This class is for transmitting an http / POST request to Web service * through a XML document * * @author Mario Spada <spadamar@spadamar.com> * @copyright Copyright (c) 2015 Mario Spada * @license http://opensource.org/licenses/GPL-2.0 GNU Public License * @package SendXMLToWebService * @version 0.1.0 2015/11/22 */ class SendXMLToWebService { /** * cURL option Connection time out * @var int */ public $connecttimeout = 10; /** * cURL option Time out * @var int */ public $timeout = 10; /** * cURL option Return transfer * @var boolean */ public $returntransfer = true; /** * cURL option SSL Verify Peer * @var boolean */ public $ssl_verifypeer = false; /** * cURL option SSL Verify Host * @var boolean */ public $ssl_verifyhost = false; /** * cURL option Post * @var boolean */ public $post = true; /** * Header Charset * @var string */ public $charset = 'utf-8'; /** * Header Content-type * @var string */ public $contentType = 'text/xml'; /** * Enable MD5 encryption for password * @var boolean */ public $md5_pass = false; /** * Enable cURL debug * @var boolean */ public $debug = true; /** * Set url (private) * @var string */ private $_url; /** * Set username (private) * @var string */ private $_user = ''; /** * Set password (private) * @var string */ private $_pass = ''; /** * Extra headers (private) * @var array */ private $_extraHeaders = array(); /** * @param string $url url to connect to Web service */ public function __construct($url) { $this->_url = $url; $this->_checkRequisites(); } /** * Send XML document to Web Service * @param string $post_string string containing XML document * @return string result string, usually in XML format */ public function sendXML($post_string) { $psLen = strlen($post_string); $headers = $this->_getHeaders($psLen); $soap_do = curl_init(); curl_setopt($soap_do, CURLOPT_URL, $this->_url); curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); curl_setopt($soap_do, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, $this->returntransfer); curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, $this->ssl_verifyhost); curl_setopt($soap_do, CURLOPT_POST, $this->post); curl_setopt($soap_do, CURLOPT_POSTFIELDS, $post_string); curl_setopt($soap_do, CURLOPT_HTTPHEADER, $headers); if (!empty($this->_user)) { curl_setopt($soap_do, CURLOPT_USERPWD, $this->_user.":".$this->_pass); } $result = curl_exec($soap_do); $err = curl_error($soap_do); curl_close ($soap_do); if ($err && $this->debug) echo "ERROR: ".$err; return $result; } /** * Set username and password * @param string $user username * @param string $pass password */ public function setCredentials($user, $pass) { $this->_user = $user; $this->_pass = md5($pass); if ($this->md5_pass) { $this->_pass = md5($this->_pass); } } /** * Set an additional header * @param string $extraHeader a valid header row */ public function setExtraHeader($extraHeader) { array_push($this->_extraHeaders,$extraHeader); } /** * Set multiple additional header at once in array format * @param array $extraHeaders an array with multiple header rows */ public function setExtraHeaders($extraHeaders) { $this->_extraHeaders = array_merge($this->_extraHeaders,$extraHeaders); } /** * Remove all additional headers */ public function resetExtraHeaders() { $this->_extraHeaders = array(); } /** * Prints out all additional headers */ public function printExtraHeaders() { print_r($this->_extraHeaders); } /** * Compose headers * @param string $psLen length of the XML string */ private function _getHeaders($psLen) { $headers = array(); array_push($headers,'Content-Type: '.$this->contentType.'; charset='.$this->charset); if (count($this->_extraHeaders) > 0) { $headers = array_merge($headers,$this->_extraHeaders); } array_push($headers,'Content-Length: '.$psLen); return $headers; } /** * Check if cURL and allow_url_fopen are enabled, check url validity */ private function _checkRequisites() { if (!function_exists('curl_version')) die("cURL is not enabled!"); if(!ini_get('allow_url_fopen')) die("allow_url_fopen is not enabled!"); if (!filter_var($this->_url, FILTER_VALIDATE_URL)) die("URL is not valid!"); return true; } } ?> |
La documentazione della classe è disponibile qui
Il pacchetto completo qui.
Per i test ho utilizzato alcuni web service gratuiti che sono disponibili a questo indirizzo: http://www.webservicex.net. Questo sito è molto interessante e pubblica dettagliatamente tutti i parametri per collegarsi ai Web service, includendo naturalmente l’XML campione per inviare i dati e l’XML che conterrà la risposta.
L’esempio di test della classe che ho scelto utilizza il web service GeoIPService per geolocalizzare un indirizzo IP:
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 require_once("SendXMLToWebService.class.php"); $xml = <<<STR <?xml version="1.0" encoding="utf-8"?> <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <GetGeoIP xmlns="http://www.webservicex.net/"> <IPAddress>8.8.8.8</IPAddress> </GetGeoIP> </soap12:Body> </soap12:Envelope> STR; $test = new SendXMLToWebService("http://www.webservicex.net/geoipservice.asmx"); $resXML = $test->sendXML($xml); $dom = new DOMDocument; $dom->loadXML($resXML); $IP = $dom->getElementsByTagName('IP'); $ReturnCodeDetails = $dom->getElementsByTagName('ReturnCodeDetails'); $CountryName = $dom->getElementsByTagName('CountryName'); $CountryCode = $dom->getElementsByTagName('CountryCode'); //print_r($resXML); echo $IP->item(0)->nodeName." = ".$IP->item(0)->nodeValue."<br>\n"; echo $ReturnCodeDetails->item(0)->nodeName." = ".$ReturnCodeDetails->item(0)->nodeValue."<br>\n"; echo $CountryName->item(0)->nodeName." = ".$CountryName->item(0)->nodeValue."<br>\n"; echo $CountryCode->item(0)->nodeName." = ".$CountryCode->item(0)->nodeValue."<br>\n"; ?> |
Questo è il risultato (utilizzando come IP un DNS di Google):
IP = 8.8.8.8 ReturnCodeDetails = Success CountryName = United States CountryCode = USA
Riferimenti: