Installation Add the package via Composer:
composer require davefx/soap-bundle
Register the bundle in config/bundles.php (Symfony 4+):
return [
// ...
Davefx\SoapBundle\DavefxSoapBundle::class => ['all' => true],
];
Configuration Publish the default config:
php artisan vendor:publish --tag=soap-bundle-config
Edit config/soap.php to define your SOAP client(s):
return [
'clients' => [
'example' => [
'wsdl' => 'http://example.com/soap?wsdl',
'options' => [
'trace' => true,
'exceptions' => true,
],
],
],
];
First SOAP Call
Inject the SoapClientManager into a service/controller:
use Davefx\SoapBundle\Manager\SoapClientManager;
public function __construct(private SoapClientManager $soapManager) {}
public function callExampleService()
{
$client = $this->soapManager->getClient('example');
$response = $client->__soapCall('MethodName', [
new \SoapParam('param1', 'value1'),
]);
return $response;
}
Service Layer Abstraction Create a dedicated service class to encapsulate SOAP logic:
namespace App\Services;
use Davefx\SoapBundle\Manager\SoapClientManager;
class ExampleSoapService
{
public function __construct(private SoapClientManager $soapManager) {}
public function getUserData(int $userId): array
{
$client = $this->soapManager->getClient('example');
$response = $client->__soapCall('GetUserData', [
new \SoapParam('userId', $userId),
]);
return $this->mapResponse($response);
}
private function mapResponse($raw): array { /* ... */ }
}
Request/Response Transformers Use decorators or middleware to transform requests/responses:
// Example: Add auth headers to every SOAP call
$client = $this->soapManager->getClient('example');
$client->__setLocation('http://example.com/soap');
$client->__setCookie('auth_token', 'xyz123');
Error Handling Centralize error handling in a base service:
try {
$response = $client->__soapCall('MethodName', $params);
} catch (\SoapFault $fault) {
throw new \RuntimeException(
"SOAP Error: [{$fault->faultcode}] {$fault->faultstring}",
0,
$fault
);
}
Dynamic Client Configuration Override client options per request:
$client = $this->soapManager->getClient('example', [
'options' => [
'trace' => true,
'exceptions' => false,
],
]);
WSDL Caching
'cache_wsdl' => WSDL_CACHE_NONE in options) to avoid stale schemas.$client->__setLocation('http://example.com/soap?wsdl=force');
SoapFault Ambiguity
SoapFault exceptions lack context. Log raw fault details:
catch (\SoapFault $fault) {
\Log::error('SOAP Fault', [
'code' => $fault->faultcode,
'string' => $fault->faultstring,
'trace' => $fault->getTraceAsString(),
]);
}
Namespace Collisions
class). Cast to arrays:
$response = (array) $client->__soapCall('MethodName', $params);
Performance
SoapClient instances (managed by the bundle) instead of creating new ones per request.__doRequest() for simple calls; prefer __soapCall().Debugging Enable tracing to inspect raw SOAP requests/responses:
$client->setUseCurl(true); // For cURL debugging
$response = $client->__soapCall('MethodName', $params);
\Log::debug('SOAP Request', ['request' => $client->__getLastRequest()]);
\Log::debug('SOAP Response', ['response' => $client->__getLastResponse()]);
Testing
Mock the SoapClientManager in PHPUnit:
$mockManager = $this->createMock(SoapClientManager::class);
$mockManager->method('getClient')
->willReturn($this->createMock(\SoapClient::class));
$this->instance(SoapClientManager::class, $mockManager);
Extension Points
$this->soapManager->addClient('dynamic', 'http://dynamic.com/soap?wsdl', []);
soap.client.created events (if supported in future versions).Configuration
'wsdl' => env('SOAP_EXAMPLE_WSDL', 'http://default.com/soap'),
AppServiceProvider).How can I help you explore Laravel packages today?