Laravel测试到SOAP WDSL的连接和异常处理


Laravel test connection to SOAP WDSL and exception handling

我使用laravel框架,我想检查与Soap服务器的连接是否成功,而不会导致应用程序因致命错误而死亡。

两者都是:

$this->client = @new SoapClient("http://some.url/test.wsdl");
                $this->session = $this->client->login("username", "password");
                if (is_soap_fault($this->session)) {
                   return "Error";
                }

这个:

try {
 $this->client = @new SoapClient("http://some.url/test.wsdl");
 $this->session = $this->client->login("username", "password");
} catch (SoapFault $e) {
    return "Error";
}

导致致命错误:

Symfony ' Component ' Debug ' Exception ' FatalErrorException
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://some.url/test.wsdl' : failed to load external entity "http://some.url/test.wsdl"

感谢

我今天也遇到了这个问题。问题是Laravel错误处理程序将这个可捕获的错误解释为致命错误,并因此中止了程序。

为了应对这种情况,您需要在Laravel的内部错误处理程序之前拦截错误。此方法因您的Laravel版本而异:

Laravel 4.*

  1. 转到您的globals.php文件。这应该在您的app'start'文件夹中
  2. 添加以下代码(感谢dmgfjaved):

    App::fatal(function($exception)
    {   //If SOAP Error is found, we don't want to FATALLY crash but catch it instead
       if(strpos($exception->getMessage(), 'SOAP-ERROR') !== FALSE)
       {
         return '';
       }
    });
    

Laravel 5.*

  1. 没有globals.php文件。所有IoC调用都通过ServiceProviders进行处理。转到app'Providers'AppServiceProvider.php
  2. 查找render()函数
  3. return parent::render($request, $e); 之前添加以下代码

    if(strpos($e->getMessage(), 'SOAP-ERROR') !== false)
    {
        return false;
    }
    

这将从错误处理程序中删除SoapFault错误类型。记住抓住SoapFault,因为Laravel不会!

试试这个:

try {
 $this->client = @new SoapClient("http://some.url/test.wsdl");
 $this->session = $this->client->login("username", "password");
} catch ('Throwable $e) {
    return "Error";
}

解决方案是实际要求Soap客户端抛出SoapFault,而不是报告E_ERROR。

当Soap客户端报告E_ERROR时,就没有什么可捕捉的了。

要修复此问题,请像这样初始化SoapClient:

$clientOptions = array(
    'exceptions' => true,
);
try {
    $client = new 'SoapClient("foo.wsdl", $clientOptions);
} catch ('SoapFault $e) {
    // Do what you need to do!;
}
try {
    $result = $client->__soapCall($method, $data);
} catch ('SoapFault $e) {
    // Do what you need to do!;
}

这就是我如何让soap在Laravel 5.1 中工作

  1. 清洁安装laravel 5.1

  2. 安装artistinweb/laravel soap

  3. 创建控制器SoapController.php

    <?php
    namespace App'Http'Controllers;
    use Artisaninweb'SoapWrapper'Facades'SoapWrapper;
    class SoapController extends Controller {
    public function demo()
    {
        // Add a new service to the wrapper
        SoapWrapper::add(function ($service) {
            $service
                ->name('currency')
                ->wsdl('http://currencyconverter.kowabunga.net/converter.asmx?WSDL')
                ->trace(true);
        });
        $data = [
            'CurrencyFrom' => 'USD',
            'CurrencyTo'   => 'EUR',
            'RateDate'     => '2014-06-05',
            'Amount'       => '1000'
        ];
        // Using the added service
        SoapWrapper::service('currency', function ($service) use ($data) {
            var_dump($service->getFunctions());
            var_dump($service->call('GetConversionAmount', [$data])->GetConversionAmountResult);
        });
    }
    }
    
  4. 在routes.php 中创建路线

    Route::get('/demo', ['as' => 'demo', 'uses' => 'SoapController@demo']);

@Adam Link提供了一个很好的提示,但在Laravel 5.1中,它似乎不再是AppServiceProvider中的渲染方法。

相反,它已被移到app''Exceptions''Handler.php