Installation:
composer require artisaninweb/laravel-soap
For Laravel 5.2+, add the service provider and facade alias to config/app.php:
'providers' => [
Artisaninweb\SoapWrapper\ServiceProvider::class,
],
'aliases' => [
'SoapWrapper' => Artisaninweb\SoapWrapper\Facade\SoapWrapper::class,
]
First Use Case:
Define a SOAP service in config/soap.php:
'services' => [
'example' => [
'wsdl' => 'http://example.com/service?wsdl',
'trace' => true,
'exceptions' => true,
],
],
Call the SOAP service in a controller or service:
$response = SoapWrapper::service('example')->__soapCall('MethodName', [$arg1, $arg2]);
config/soap.php for easy maintenance.
'services' => [
'payment_gateway' => [
'wsdl' => env('PAYMENT_GATEWAY_WSDL'),
'trace' => env('SOAP_TRACE', false),
'exceptions' => true,
'options' => [
'login' => env('PAYMENT_GATEWAY_LOGIN'),
'password' => env('PAYMENT_GATEWAY_PASSWORD'),
],
],
],
Facade-Based Calls:
// Call a SOAP method
$result = SoapWrapper::service('payment_gateway')->Charge([
'amount' => 100.00,
'currency' => 'USD',
]);
// Handle complex types
$complexData = [
'Customer' => [
'@attributes' => ['id' => '123'],
'Name' => 'John Doe',
],
];
$response = SoapWrapper::service('example')->CreateCustomer($complexData);
Dynamic Service Binding:
$serviceName = request()->input('service');
$response = SoapWrapper::service($serviceName)->__soapCall('Method', [$data]);
Exceptions: Enable exceptions in config to throw SoapFault exceptions.
try {
$response = SoapWrapper::service('example')->FaultyMethod();
} catch (\SoapFault $e) {
Log::error('SOAP Error: ' . $e->getMessage());
return response()->json(['error' => 'Service unavailable'], 500);
}
Fallback Logic:
if (SoapWrapper::service('example')->__getLastRequestHeaders()) {
// Log request/response for debugging
Log::debug('SOAP Request:', [
'headers' => SoapWrapper::service('example')->__getLastRequestHeaders(),
'response' => SoapWrapper::service('example')->__getLastResponse(),
]);
}
Service Container Binding: Bind the SOAP service to the container for dependency injection:
$this->app->bind('payment.gateway', function ($app) {
return SoapWrapper::service('payment_gateway');
});
Queue Jobs: Offload SOAP calls to queues to avoid timeouts:
dispatch(new ProcessPaymentJob($orderId));
class ProcessPaymentJob implements ShouldQueue {
public function handle() {
$response = SoapWrapper::service('payment_gateway')->Charge($this->paymentData);
// Process response...
}
}
$this->app->instance('payment.gateway', Mockery::mock([
'Charge' => ['success' => true],
]));
$response = $this->app->make('payment.gateway')->Charge([...]);
$this->assertTrue($response['success']);
SoapWrapper::service('example')->__setLocation('http://updated-wsdl-url');
SoapWrapper::service('example')->__setUse('literal');
options key in config:
'services' => [
'secure_service' => [
'wsdl' => 'http://secure.example.com/wsdl',
'options' => [
'stream_context' => stream_context_create([
'http' => [
'header' => "Authorization: Bearer token123\r\n",
],
]),
],
],
],
config/soap.php:
'options' => [
'connection_timeout' => 30,
'execution_timeout' => 60,
],
SoapWrapper::service()->__getLastResponse() to inspect raw XML:
$rawResponse = SoapWrapper::service('example')->__getLastResponse();
$dom = new \DOMDocument();
$dom->loadXML($rawResponse);
// Parse manually if needed
// Good: Uses config/soap.php
$response = SoapWrapper::service('example')->Method();
// Avoid unless necessary
$client = new \SoapClient('http://example.com/wsdl');
SoapWrapper class to add reusable logic:
class CustomSoapWrapper extends \Artisaninweb\SoapWrapper\Facade\SoapWrapper {
public static function retry($serviceName, $method, $args, $retries = 3) {
$lastError = null;
for ($i = 0; $i < $retries; $i++) {
try {
return parent::service($serviceName)->$method($args);
} catch (\SoapFault $e) {
$lastError = $e;
sleep(2 ** $i); // Exponential backoff
}
}
throw $lastError;
}
}
class SoapLoggingMiddleware {
public function handle($request, Closure $next) {
$service = SoapWrapper::service('example');
$service->__setLocation('http://example.com/wsdl');
$response = $next($request);
Log::debug('SOAP Request:', [
'headers' => $service->__getLastRequestHeaders(),
'response' => $service->__getLastResponse(),
]);
return $response;
}
}
$services = DB::table('soap_services')->get();
foreach ($services as $service) {
config(['soap.services.' . $service->name => [
'wsdl' => $service->wsdl_url,
'options' => json_decode($service->options, true),
]]);
}
trait SoapTestHelper {
protected function mockSoapService($serviceName, $methods = []) {
$mock = Mockery::mock();
foreach ($methods as $method => $response) {
$mock->shouldReceive($method)->andReturn($response);
}
$this->app->instance("soap.{$serviceName}", $mock);
}
}
'trace' => true in config logs raw SOAP requests/responses to storage/logs/soap.log..env for sensitive data like WSDL URLs or credentials:How can I help you explore Laravel packages today?