-
-
Save RobThree/2490351 to your computer and use it in GitHub Desktop.
<?php | |
//Drop-in replacement for PHP's SoapClient class supporting connect and response/transfer timeout | |
//Usage: Exactly as PHP's SoapClient class, except that 3 new options are available: | |
// timeout The response/transfer timeout in milliseconds; 0 == default SoapClient / CURL timeout | |
// connecttimeout The connection timeout; 0 == default SoapClient / CURL timeout | |
// sslverifypeer FALSE to stop SoapClient from verifying the peer's certificate | |
class SoapClientTimeout extends SoapClient | |
{ | |
private $timeout = 0; | |
private $connecttimeout = 0; | |
private $sslverifypeer = true; | |
public function __construct($wsdl, $options) { | |
//"POP" our own defined options from the $options array before we call our parent constructor | |
//to ensure we don't pass unknown/invalid options to our parent | |
if (isset($options['timeout'])) { | |
$this->__setTimeout($options['timeout']); | |
unset($options['timeout']); | |
} | |
if (isset($options['connecttimeout'])) { | |
$this->__setConnectTimeout($options['connecttimeout']); | |
unset($options['connecttimeout']); | |
} | |
if (isset($options['sslverifypeer'])) { | |
$this->__setSSLVerifyPeer($options['sslverifypeer']); | |
unset($options['sslverifypeer']); | |
} | |
//Now call parent constructor | |
parent::__construct($wsdl, $options); | |
} | |
public function __setTimeout($timeoutms) | |
{ | |
if (!is_int($timeoutms) && !is_null($timeoutms) || $timeoutms<0) | |
throw new Exception("Invalid timeout value"); | |
$this->timeout = $timeoutms; | |
} | |
public function __getTimeout() | |
{ | |
return $this->timeout; | |
} | |
public function __setConnectTimeout($connecttimeoutms) | |
{ | |
if (!is_int($connecttimeoutms) && !is_null($connecttimeoutms) || $connecttimeoutms<0) | |
throw new Exception("Invalid connecttimeout value"); | |
$this->connecttimeout = $connecttimeoutms; | |
} | |
public function __getConnectTimeout() | |
{ | |
return $this->connecttimeout; | |
} | |
public function __setSSLVerifyPeer($sslverifypeer) | |
{ | |
if (!is_bool($sslverifypeer)) | |
throw new Exception("Invalid sslverifypeer value"); | |
$this->sslverifypeer = $sslverifypeer; | |
} | |
public function __getSSLVerifyPeer() | |
{ | |
return $this->sslverifypeer; | |
} | |
public function __doRequest($request, $location, $action, $version, $one_way = FALSE) | |
{ | |
if (($this->timeout===0) && ($this->connecttimeout===0)) | |
{ | |
// Call via parent because we require no timeout | |
$response = parent::__doRequest($request, $location, $action, $version, $one_way); | |
} | |
else | |
{ | |
// Call via Curl and use the timeout | |
$curl = curl_init($location); | |
if ($curl === false) | |
throw new Exception('Curl initialisation failed'); | |
$options = array( | |
CURLOPT_VERBOSE => false, | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_POST => true, | |
CURLOPT_POSTFIELDS => $request, | |
CURLOPT_HEADER => false, | |
CURLOPT_NOSIGNAL => true, //http://www.php.net/manual/en/function.curl-setopt.php#104597 | |
CURLOPT_HTTPHEADER => array(sprintf('Content-Type: %s', $version == 2 ? 'application/soap+xml' : 'text/xml'), sprintf('SOAPAction: %s', $action)), | |
CURLOPT_SSL_VERIFYPEER => $this->sslverifypeer | |
); | |
if ($this->timeout>0) { | |
if (defined('CURLOPT_TIMEOUT_MS')) { //Timeout in MS supported? | |
$options[CURLOPT_TIMEOUT_MS] = $this->timeout; | |
} else { //Round(up) to second precision | |
$options[CURLOPT_TIMEOUT] = ceil($this->timeout/1000); | |
} | |
} | |
if ($this->connecttimeout>0) { | |
if (defined('CURLOPT_CONNECTTIMEOUT_MS')) { //ConnectTimeout in MS supported? | |
$options[CURLOPT_CONNECTTIMEOUT_MS] = $this->connecttimeout; | |
} else { //Round(up) to second precision | |
$options[CURLOPT_CONNECTTIMEOUT] = ceil($this->connecttimeout/1000); | |
} | |
} | |
if (curl_setopt_array($curl, $options) === false) | |
throw new Exception('Failed setting CURL options'); | |
$response = curl_exec($curl); | |
if (curl_errno($curl)) | |
throw new Exception(curl_error($curl)); | |
curl_close($curl); | |
} | |
// Return? | |
if (!$one_way) | |
return ($response); | |
} | |
} |
Made first attempt: https://gist.github.com/4117914
Needs some refactoring and lots of testing...
not working!
to mimic the behaviour php should have for SoapClient, this client should per default respect default_socket_timeout, no?
staabm : read the following post to understand why the default_socket_timeout does not work if data has already been sent : http://www.darqbyte.com/2009/10/21/timing-out-php-soap-calls/
Please , as I pass parameters to this class after that I declare ? example :
$fecha_soap = date ( 'Y-m-d\TH:i:s' ) ;
$xml = '
soapenv:Body
tem:ConsultaSaldo
tem:consulta
poin:ClaveVenta0104/poin:ClaveVenta
poin:ComercioId2783/poin:ComercioId
poin:FechaHoraTransaccion' . $fecha_soap . '/poin:FechaHoraTransaccion
poin:PasswordPpay35085*/poin:Password
poin:TerminalId197/poin:TerminalId
poin:TransaccionId1/poin:TransaccionId
/tem:consulta
/tem:ConsultaSaldo
/soapenv:Body
' ;
$wsdl = "https://col.pointpay.net/WCF/PointPay.Bridge.webService.WebServiceCO.svc?wsdl" ;
$location = "https://col.pointpay.net/WCF/PointPay.Bridge.webService.WebServiceCO.svc" ;
$soap_client = new SoapClientTimeout($wsdl , array ( "timeout" => 10, "connecttimeout"=> 15 ));
$imagen = $soap_client-> __doRequest ( $xml , $location , "ConsultaSaldo" , 2 , FALSE );
print_r ( $imagen ) ;
Fatal error: Uncaught exception 'Exception' with message 'Resolving timed out after 12 milliseconds' in /var/www/html/recargas/index_soap.php:131 Stack trace: #0 /var/www/html/recargas/index_soap.php(179): SoapClientTimeout->__doRequest(' ...', 'https://col.poi...', 'ConsultaSaldo', 2, false) #1 {main} thrown in /var/www/html/recargas/index_soap.php on line 131
Response is always false. Looks like it does not wait for response at all.
Hmm, need to combine this with http://tcsoftware.net/downloads/php/download.php?file=SoapClientAuth for the ultimate SoapClient class :P