我在应用程序中使用Laravel SoapClient Wrapper进行Soap调用。我把它用作模型扩展,这样我就可以在每个需要soap调用的控制器中轻松地使用它。到目前为止一切都很好,但我想确保我的应用程序不会在WSDL URL不正确或SOAP服务器上不存在服务调用等情况下崩溃。我试图"尝试捕获"代码的这些部分,但没有成功。我的代码是下一个:
use Artisaninweb'SoapWrapper'Extension'SoapService;
use Artisaninweb'SoapWrapper'Facades'SoapWrapper;
class Wsdl extends SoapService{
protected $name = 'test';
protected $wsdl;
protected $trace = true;
public function __construct($wsdl)
{
$this->wsdl = $wsdl;
SoapWrapper::add(function ($service) {
$service
->name($this->name)
->wsdl($this->wsdl)
->trace(true);
});
}
public function functions()
{
return $this->getFunctions();
}
public function bills(Array $data)
{ //function for get bills for one customer
$bill= null;
try{
SoapWrapper::service($this->name, function ($service) use ($data, &$bill) {
$bill= $service->call('getBill', [$data])->billStructure;
});
return $bill;
}
catch('SoapFault $e){
//dd("soapFault");
return null;
}
catch('ErrorException $e){
//dd("errorException");
return null;
}
}
}
在我的控制器中,我称这种型号为
try{
$soap = new Wsdl('link');
$data = [
'param' => 1
];
$result= $soap->bills($data);
}
catch('Exception $e){
//problem
flash()->error("There was a problem with getting data, try to contact administrator");
}
catch('FatalErrorException $e){
//problem
flash()->error("There was a problem with getting data, try to contact administrator");
}
我设法发现了两个错误:
- 如果我在中有不存在的XML结构(响应的XML名称错误)
$bill=$service->call('getBill',[$data])->billStructure
- 如果我在$bill=$service->call('getBill',[$data])->billStructure中有错误的服务名称
我抓不到的错误是:
如果我的WSDL链接错误(不正确),那么我会得到
服务中的致命错误异常。php第356行:SOAP-错误:分析WSDL:无法从"链接"加载:无法加载外部实体"链接"
所以我的问题是如何处理该异常,以便向我的应用程序的用户提供消息(获取数据时出现问题,请尝试联系管理员…)?
在我的代码中,你可以看到我尝试过某种Try-Catch,但没有成功,所以任何建议都很好。
问题出现在Laravel框架中。Laravel将此错误解释为致命错误,并因此中止了我的应用程序。我使用的是Laravel 5.1。为了完成这项工作,他不得不改变一些总体设置。
在应用程序''异常中,您需要添加一些框架忽略致命错误异常的代码。默认情况下,函数render()
看起来像这个
public function render($request, Exception $e)
{
if ($e instanceof ModelNotFoundException) {
$e = new NotFoundHttpException($e->getMessage(), $e);
}
return parent::render($request, $e);
}
要使这个错误不会崩溃你的应用程序添加一个额外的条件,然后功能看起来像这个
public function render($request, Exception $e)
{
if ($e instanceof ModelNotFoundException) {
$e = new NotFoundHttpException($e->getMessage(), $e);
}
if(strpos($e->getMessage(), 'SOAP-ERROR') !== false)
{
return false;
}
return parent::render($request, $e);
}
我认为,在1天的失败后,这是最好的解决方案(当然,如果你使用Laravel 5.1).对于纯php有几种方法可以做到:
- 编写自己的错误处理程序
- 打开和关闭x_debug
- 尝试从不正确的wsdl中获取内容,然后以某种方式进行验证
//Could manipulate:
public function render($request, Exception $e)
{
switch (get_class($e)) {
case 'SoapFault':
return 'Erro do serviço no cliente: '.$e->faultstring;
break;
default:
return parent::render($request, $e);
break;
}
}