econea/nusoap
NuSOAP is a pure-PHP library for creating and consuming SOAP 1.1 web services with WSDL 1.1 and HTTP 1.0/1.1 support. No PHP extensions required. Install via Composer and call methods on the client.
Installation
composer require econea/nusoap
composer require "econea/nusoap:^0.9.20"
First Use Case: SOAP Client
use Econea\NuSoap\Client;
$client = new Client('https://example.com/soap-service?wsdl');
$response = $client->call('MethodName', ['param1' => 'value1']);
print_r($response);
First Use Case: SOAP Server
use Econea\NuSoap\Server;
$server = new Server('https://example.com/soap-service.wsdl');
$server->register('MethodName');
$server->handle();
Where to Look First
src/Econea/NuSoap/ for core classes like Client, Server, and Fault.examples/ directory now includes dedicated server examples added in v0.10.0 — the fastest way to see a working Server + WSDL round-trip.contributte/doctrine-orm and added E2E server tests (Toolkit::test()). The server tests are the best reference for expected request/response shapes.charencoding property.Instantiation
$client = new Client(
'https://example.com/soap-service?wsdl',
[
'trace' => 1, // Enable request/response logging
'exceptions' => true, // Throw exceptions on errors
'strict_warnings' => true, // Surface undefined output message warnings
]
);
Calling Methods
// Simple call
$response = $client->call('GetData', ['id' => 123]);
// Complex call with namespaces
$response = $client->call(
'ComplexMethod',
['param' => ['@attributes' => ['ns' => 'urn:namespace']]],
['namespace' => 'urn:namespace']
);
Handling Responses
if ($client->fault) {
throw new \RuntimeException($client->faultstring);
}
$result = $client->getResponse();
Debugging
$client->setDebugLevel(9);
echo '<pre>' . htmlspecialchars($client->getDebug(), ENT_QUOTES) . '</pre>';
Legacy SOAP services frequently expect ISO-8859-1 rather than UTF-8. The charencoding property is now configurable rather than hard-coded:
$client = new Client($wsdlUrl);
// Getter/setter added in #144
$client->setCharencoding('ISO-8859-1');
$previous = $client->getCharencoding(); // 'UTF-8' by default
This removes the need for the previous hack of mutating the property reflectively or subclassing. Set it before the first call() so it is applied during WSDL parsing and envelope serialisation.
Registering Methods
$server = new Server('https://example.com/soap-service.wsdl');
$server->register('GetUserData');
$server->register('UpdateUser', ['in' => 'userId', 'out' => 'userData']);
Handling Requests
$server->setObject(new class {
public function GetUserData($userId)
{
return ['id' => $userId, 'name' => 'John Doe'];
}
});
Custom WSDL Handling
$server->wsdl->addComplexType(
'UserData',
'complexType',
'struct',
'sequence',
[
['name' => 'id', 'type' => 'xsd:int'],
['name' => 'name', 'type' => 'xsd:string'],
]
);
Server-side Encoding
$server = new Server('https://example.com/soap-service.wsdl');
$server->setCharencoding('ISO-8859-1'); // match the client/contract
$server->register('GetUserData');
$server->handle();
Laravel Service Providers Bind the client to the container for dependency injection, and expose the encoding as config:
$this->app->bind(Client::class, function ($app) {
$client = new Client(config('services.soap.endpoint'), [
'trace' => $app['config']['services.soap.trace'],
'strict_warnings' => true,
]);
$client->setCharencoding($app['config']['services.soap.encoding'] ?? 'UTF-8');
return $client;
});
Add SOAP_ENCODING to config/services.php so per-integration encoding is environment-driven — this is the single most useful new knob in v0.10.0.
Middleware for SOAP Requests Use Laravel middleware to validate or transform SOAP requests before they reach the server:
$server->register('SecureMethod', [], ['middleware' => 'validateSoapRequest']);
Caching WSDL Cache the parsed WSDL to avoid repeated network calls. Note that encoding now affects serialisation, so key the cache on it:
$key = 'soap_wsdl_' . md5($wsdlUrl . $encoding);
$wsdlCache = Cache::remember($key, 3600, function () use ($wsdlUrl, $encoding) {
$client = new Client($wsdlUrl, ['strict_warnings' => true]);
$client->setCharencoding($encoding);
return $client;
});
Upgrading from 0.9.x
Bump the PHP constraint in composer.json ("php": "^8.2") and run your SOAP integration tests. The 0.9.x code paths that emitted PHP 8.5 deprecations are fixed, so the upgrade is a net reduction in noise — but confirm your CI images are 8.2+ before merging.
PHP 8.2 Minimum (Breaking in v0.10.0)
composer.json was modernised and now requires PHP >= 8.2. Installs on 8.1 and below will fail resolution rather than warn."econea/nusoap": "^0.9.20" on older runtimes, or upgrade PHP. Note that the linter/test CI now only covers PHP 8.2–8.5, so 5.6–8.1 is no longer verified by the maintainers even though the code may still run.Encoding Mismatch Between Client and Server
charencoding defaults to UTF-8. A service publishing ISO-8859-1 will produce mojibake or schema validation faults on accented characters.$client->setCharencoding('ISO-8859-1');
// ...
$server->setCharencoding('ISO-8859-1');
Namespace Conflicts
use Econea\NuSoap\Client as NuSoapClient;
WSDL Generation Issues
wsdl::$schemaTargetNamespace deprecation warning on PHP 8.2+ was fixed in v0.10.0, but custom overrides still need care.Server class:
$server->wsdl->schemaTargetNamespace = 'urn:custom-namespace';
Large Payloads
post_max_size, memory_limit).$client->setUseCurl(true);
$client->setCurlOption(CURLOPT_TIMEOUT, 30);
Fault Handling
exceptions is false.$client->fault after calls:
if ($client->fault) {
Log::error('SOAP Fault: ' . $client->faultstring);
throw new \RuntimeException($client->faultstring, $client->faultcode);
}
Legacy Superglobals Removed
$HTTP_SERVER_VARS was removed in v0.10.0. Any custom subclass or copied-from-old-NuSOAP snippet referencing it will break.$_SERVER directly, or better, inject request data instead of reading globals.Undefined Output Messages
strict_warnings; v0.10.0 additionally fixed the unrelated $tt_ns undefined-variable warning in serialize_val(), which previously polluted debug output.new Client($wsdlUrl, ['strict_warnings' => true]) and define all output parameters in the WSDL.Enable Full Debugging
$client->setDebugLevel(9); // Max verbosity
echo '<pre>' . htmlspecialchars($client->getDebug(), ENT_QUOTES) . '</pre>';
$client->getLastRequest() and $client->getLastResponse() for raw XML — this is the fastest way to spot an encoding problem (look at the XML declaration's encoding= attribute).Logging
Log::debug('SOAP Request', [
'request' => $client->getLastRequest(),
'encoding' => $client->getCharencoding(),
]);
Common Errors
SOAP-ENV:Server: Server-side error. Check the server's debug logs.SOAP-ENV:VersionMismatch: WSDL or SOAP version mismatch. Verify the WSDL URL and SOAP version.SOAP-ENV:Client: Client-side error (e.g. invalid parameters). Validate input data.strict_warnings, ensure all output parameters are defined in the WSDL or method signature.getCharencoding() on both ends before blaming the payload.Deprecation Noise (PHP 8.2–8.5)
curl_close(), non-canonical cast, and wsdl::$schemaTargetNamespace deprecations. If you still see these after upgrading, you are almost certainly autoloading a stale copy or a second NuSOAP fork — run composer show econea/nusoap and composer why-not econea/nusoap 0.10.0.error_reporting(E_ALL)) so they do not accumulate silently.Custom Fault Handling
class CustomFault extends \Econea\NuSoap\Fault
{
public function __construct($faultcode, $faultstring, $faultactor = null)
{
parent::__construct($faultcode, $faultstring, $faultactor);
// Add custom logic (e.g. logging, retries)
}
}
Client Request/Response Interception
$client->setMiddleware(function ($request, $response, $client) {
// Pre-process request
$request = str_replace('old', 'new', $request);
return [$request, $response];
});
Verify these hook names against src/Econea/NuSoap/Client.php on the version you install — this surface is not covered by the 0.10.0 release notes.
Custom Transport Layer
$client->setUseCurl(false);
$client->setTransport(new CustomTransport());
Encoding-aware Subclass Where you cannot reach the client instance (e.g. deep inside a legacy service class), a thin subclass that applies encoding in the constructor keeps the concern in one place:
class Latin1Client extends \Econea\NuSoap\Client
{
public function __construct(string $wsdl, array $options = [])
{
parent::__construct($wsdl, $options);
$this->setCharencoding('ISO-8859-1');
}
}
Testing Use Laravel's HTTP fakes to stub SOAP responses, and lean on the new upstream E2E server tests as a reference for realistic envelopes:
Http::fake([
'https://example.com/soap-service' => Http::response($mockXml, 200),
]);
How can I help you explore Laravel packages today?