Installation
composer require awelara/besimple-soap-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Awelara\BeSimpleSoapBundle\AwelaraBeSimpleSoapBundle::class => ['all' => true],
];
First Use Case: Consuming a SOAP Service
Define a client configuration in config/packages/besimple_soap.yaml:
besimple_soap:
clients:
example_client:
wsdl: "http://example.com/service?wsdl"
options:
trace: true
exceptions: true
Inject the client in a service:
use Awelara\BeSimpleSoapBundle\Client\SoapClient;
class ExampleService
{
public function __construct(private SoapClient $exampleClient) {}
public function callService()
{
$result = $this->exampleClient->__soapCall('MethodName', ['arg1' => 'value']);
return $result;
}
}
First Use Case: Exposing a SOAP Service
Define a server configuration in config/packages/besimple_soap.yaml:
besimple_soap:
servers:
example_server:
uri: "/soap"
class: "App\Service\SoapService"
methods:
- "getData"
- "updateData"
Implement the service class:
class SoapService
{
public function getData($param) { /* ... */ }
public function updateData($param) { /* ... */ }
}
Dynamic Client Configuration Use dependency injection to create clients dynamically:
$client = $container->get('besimple_soap.client.example_client');
Handling Complex Types Map complex types via annotations or XML schemas:
use Awelara\BeSimpleSoapBundle\Annotation as Soap;
class ComplexType
{
/**
* @Soap\SoapType(name="complexType")
*/
public $field;
}
Asynchronous Requests Use Symfony’s Messenger component with the SOAP client:
$message = new SoapCallMessage('MethodName', ['arg' => 'value']);
$this->messageBus->dispatch($message);
Method-Level Security Secure endpoints with Symfony’s security system:
# config/packages/security.yaml
access_control:
- { path: ^/soap, roles: ROLE_SOAP_USER }
WSDL Generation Auto-generate WSDL dynamically:
$wsdl = $this->container->get('besimple_soap.server.example_server')->getWsdl();
Integration with Symfony Forms Validate SOAP payloads using Symfony’s form system:
$form = $this->createForm(SoapDataType::class, $data);
if ($form->isSubmitted() && $form->isValid()) { /* ... */ }
Request-Response Cycle
besimple_soap:
logging: true
Testing
Use HttpClient to mock SOAP calls:
$client = $this->createMock(SoapClient::class);
$client->method('__soapCall')->willReturn(['mocked' => 'response']);
$this->container->set('besimple_soap.client.example_client', $client);
PHP SOAP Extension Quirks
ext-soap is enabled (php -m | grep soap).soap.wsdl_cache_enabled=0 in php.ini for dynamic services.Namespace Conflicts SOAP namespaces must match exactly. Use fully qualified class names:
namespace App\Soap\Types;
class User { /* ... */ }
Large Payloads
Increase soap.wsdl_cache and memory_limit for large WSDLs or payloads.
Symfony 4+ Compatibility
# config/services.yaml
Awelara\BeSimpleSoapBundle\Client\SoapClient: ~
Enable SOAP Traces
besimple_soap:
clients:
example_client:
options:
trace: true
Access traces via:
$client->__getLastRequest();
$client->__getLastResponse();
WSDL Validation Validate WSDLs using online tools (e.g., WSDL Analyzer) before integration.
Common Errors
SOAP-ERROR: Parsing WSDL: Check WSDL URL and XML syntax.SOAP-ERROR: Encoding: Ensure types match (e.g., string vs. int).Class not found: Verify namespace and annotation usage.Reuse Clients Cache clients in services to avoid re-parsing WSDLs:
private SoapClient $client;
public function __construct(SoapClient $client) {
$this->client = $client;
}
Custom SOAP Headers Add headers dynamically:
$header = new SoapHeader('namespace', 'headerData', ['key' => 'value']);
$this->client->__setSoapHeaders([$header]);
Performance
besimple_soap:
clients:
example_client:
options:
wsdl_cache_enabled: false
curl for non-SOAP endpoints if possible (faster than SOAP).Extending Functionality
besimple_soap.serializer to handle custom types.besimple_soap.client.event).services.yaml to configure PHP SOAP settings:
php:
ini:
soap.wsdl_cache_enabled: "0"
How can I help you explore Laravel packages today?