besimple/soap
BeSimpleSoap provides tools to build SOAP and WSDL-based web services in PHP, including a Symfony2 bundle plus enhanced SoapClient/SoapServer with SwA, MTOM, and WS-Security support, along with shared utilities and WSDL generation.
Installation:
composer require besimple/soap
For Symfony projects, add besimple/soap-bundle to composer.json:
"require": {
"besimple/soap-bundle": "^0.2"
}
First Use Case (Client):
use BeSimple\SoapClient\SoapClient;
$client = new SoapClient('http://example.com/service?wsdl', [
'trace' => 1,
'exceptions' => true,
]);
$result = $client->someMethod(['param1' => 'value']);
First Use Case (Server):
use BeSimple\SoapServer\SoapServer;
use BeSimple\SoapWsdl\Wsdl;
$wsdl = new Wsdl('http://example.com/schema.xsd');
$wsdl->addMethod('someMethod', 'http://example.com/namespace', 'string', 'string');
$server = new SoapServer($wsdl, ['trace' => 1]);
$server->handle();
Key Files to Review:
src/BeSimple/SoapClient/README.md (for client-side usage)src/BeSimple/SoapServer/README.md (for server-side setup)src/BeSimple/SoapWsdl/README.md (for WSDL generation)Service Consumption:
$client = new SoapClient('service.wsdl', [
'features' => SoapClient::FEATURE_MTOM, // Enable MTOM for binary data
'wsdl_cache' => '/tmp/wsdl_cache', // Cache WSDL
]);
$response = $client->__soapCall('methodName', [$args]);
Handling Complex Types:
$client = new SoapClient('service.wsdl');
$complexObject = new \stdClass();
$complexObject->field1 = 'value1';
$complexObject->field2 = 'value2';
$result = $client->methodAcceptingComplexType($complexObject);
Error Handling:
try {
$client->__soapCall('methodName', [$args]);
} catch (\SoapFault $fault) {
\Log::error('SOAP Error: ' . $fault->getMessage());
throw new \RuntimeException('SOAP request failed', 0, $fault);
}
Logging and Debugging:
$client = new SoapClient('service.wsdl', ['trace' => 1]);
$client->__soapCall('methodName', [$args]);
$request = $client->__getLastRequest();
$response = $client->__getLastResponse();
\Log::debug("Request: " . $request);
\Log::debug("Response: " . $response);
Basic Server Setup:
use BeSimple\SoapServer\SoapServer;
use BeSimple\SoapWsdl\Wsdl;
$wsdl = new Wsdl('http://example.com/schema.xsd');
$wsdl->addMethod('getData', 'http://example.com/namespace', 'string', 'string');
$server = new SoapServer($wsdl, [
'classmap' => ['MyClass' => 'App\\Model\\MyClass'],
]);
$server->handle();
Handling Requests:
$server = new SoapServer($wsdl);
$server->setClass('MyServiceClass'); // Bind to a class
$server->handle();
Custom Logic:
class MyServiceClass {
public function getData($input) {
// Custom logic
return ['result' => $input . '_processed'];
}
}
WS-Security Integration:
$server = new SoapServer($wsdl, [
'wsSecurity' => [
'username' => 'admin',
'password' => 'secret',
],
]);
Laravel Integration:
besimple/soap-bundle for Symfony-like integration in Laravel.SoapClient/SoapServer to the Laravel container:
$app->bind('soap.client', function ($app) {
return new SoapClient('service.wsdl', ['trace' => 1]);
});
Middleware for SOAP:
// Example middleware to log SOAP requests
$app->middleware(function ($request, $next) {
if ($request->isSoap()) {
\Log::info('SOAP Request: ' . $request->getContent());
}
return $next($request);
});
Testing:
Mockery to mock SOAP responses in tests:
$mock = Mockery::mock('overload:BeSimple\SoapClient\SoapClient');
$mock->shouldReceive('__soapCall')->andReturn(['success' => true]);
WSDL Caching:
'wsdl_cache' => null) to avoid stale WSDL issues.Namespace Conflicts:
$wsdl->addMethod('method', 'http://example.com/namespace/v1', 'string', 'string');
MTOM/SwA Limitations:
php-soap and php-xml extensions are enabled.SoapClient::FEATURE_MTOM and adjust upload_max_filesize in php.ini.WS-Security:
phpseclib (composer require phpseclib/phpseclib). Add to composer.json:
"require": {
"phpseclib/phpseclib": "^2.0"
}
Complex Types:
stdClass or custom objects with @soap annotations:
/**
* @soap
*/
class MyComplexType {
public $field1;
public $field2;
}
Enable Traces:
$client = new SoapClient('service.wsdl', ['trace' => 1]);
// After call:
\Log::debug("Request: " . $client->__getLastRequest());
\Log::debug("Response: " . $client->__getLastResponse());
Check Headers:
$fault->getMessage() and $fault->getDetail().Validate WSDL:
SoapClient Options:
exceptions: Set to true to throw SoapFault exceptions instead of returning false.location: Override the service endpoint URL.uri: Override the target namespace.SoapServer Options:
classmap: Map XML types to PHP classes (e.g., ['MyType' => 'App\\Model\\MyType']).persistent: Use persistent connections (rarely needed).WS-Security:
wsSecurity option is an array:
'wsSecurity' => [
'username' => 'user',
'password' => 'pass',
'signature' => true, // Optional
]
Custom SoapClient:
Extend BeSimple\SoapClient\SoapClient to add custom logic:
class CustomSoapClient extends SoapClient {
public function __construct($wsdl, $options = []) {
parent::__construct($wsdl, $options);
$this->addCustomHeader();
}
private function addCustomHeader() {
$this->__setCookie('custom_token', 'abc123');
}
}
WSDL Generators:
Use BeSimple\SoapWsdl\Wsdl to dynamically generate WSDL:
$wsdl = new Wsdl('http://example.com/schema.xsd');
$wsdl->addMethod('dynamicMethod', 'http://example.com/namespace', 'string',
How can I help you explore Laravel packages today?