公司里有很多服务都是用curl或者soap来连接第三方公司做的服务来交换数据的。最近新增了一个需求,就是在第三方服务发布的时候,连接不上对方服务器的时候,需要重试。若因其他原因导致业务处理失败,则视为失败,不再调用。思路是判断当curl或者soap连接不上对方服务器时,抛出TimeoutException,捕获后做重试处理。由于其他错误引发的异常被视为失败。curl处理$ch=curl_init($url);$options=array(CURLOPT_RETURNTRANSFER=>true,CURLOPT_CONNECTTIMEOUT=>5,//5秒连接时间CURLOPT_TIMEOUT=>30,//30秒请求等待时间);curl_setopt_array($ch,$options);$response=curl_exec($ch);如果($no=curl_errno($ch)){$error=curl_error($ch);curl_close($ch);//$noerrorcode7为连接号,28已连接但请求返回超时if(in_array(intval($no),[7,28],true)){thrownewTimeoutException('连接或请求超时出'.$error,$no);}}curl_close($ch);soap处理php文档没有详细写soap超时或连接失败返回的具体代码。如果业务处理失败或者连接失败,会抛出SoapFault异常。看一看。php的源码找到了,还有定义的php源文件位置/ext/soap/php_http.c定义错误码内容add_soap_fault(this_ptr,"HTTP","UnabletoparseURL",NULL,NULL);add_soap_fault(this_ptr,"HTTP","Unknownprotocol.Onlyhttpandhttpsareallowed.",NULL,NULL);add_soap_fault(this_ptr,"HTTP","SSLsupporti在此版本中不可用",NULL,NULL);add_soap_fault(this_ptr,"HTTP","无法连接到主机",NULL,NULL);add_soap_fault(this_ptr,"HTTP","发送HTTPSOAP请求失败",NULL,NULL);add_soap_fault(this_ptr,"HTTP","创建流失败??",NULL,NULL);add_soap_fault(this_ptr,"HTTP","ErrorFetchinghttpheaders",NULL,NULL);add_soap_fault(this_ptr,"HTTP","获取http正文时出错,无内容长度,连接关闭或数据分块",NULL,NULL);add_soap_fault(this_ptr,"HTTP","达到重定向限制,中止",NULL,NULL);add_soap_fault(this_ptr,"HTTP","没有收到xml文档",NULL,err);add_soap_fault(this_ptr,"HTTP","UnknownContent-Encoding",NULL,NULL);add_soap_fault(this_ptr,"HTTP","Can'tuncompresscompressedresponse",NULL,NULL);add_soap_fault(this_ptr,"HTTP",http_msg,NULL,NULL);从代码可以看出,连接失败会返回一个HTTP代码,soap是不像curl那样,有具体的代码可以区分两者。只有通过这段代码才能判断是超时或者连接失败等网络问题。具体代码如下:ini_set('default_socket_timeout',30);//定义响应超时为30秒try{$options=array('cache_wsdl'=>0,'connection_timeout'=>5,//定义连接超时为5秒);libxml_disable_entity_loader(假);$client=new\SoapClient($url,$options);返回$client->__soapCall($function_name,$arguments);}catch(\SoapFault$e){//超时,无法连接if($e->faultcode=='HTTP'){thrownewTimeoutException('连接或请求超时',$e->getCode());}}可以连接soap服务,但是如果客户端或者服务端有问题,$e->faultcode会返回WSDL,用这个来判断上面的方法对于php使用soap和curl捕获请求超时和连接暂停
