Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nusoap Laravel Package

fergusean/nusoap

NuSOAP for Laravel: a lightweight wrapper around the NuSOAP library for building and consuming SOAP web services. Create SOAP servers or clients with WSDL support without requiring PHP's SOAP extension.

Deep Wiki
Context7

Getting Started

Install with Composer:

composer require fergusean/nusoap

This is a straight re-packaging of the classic NuSOAP library, so there is no Laravel service provider, facade, config file, or published assets. The package registers its classes via Composer's autoloader (typically a classmap pointing at a lib/ directory), so after composer dump-autoload the classes are available in the global namespace:

$client = new \nusoap_client('https://example.com/service?wsdl', 'wsdl');
$client->setCredentials($user, $pass);
$result = $client->call('GetCustomer', ['id' => 42]);

if ($client->getError()) {
    // returns a string, not an exception
    throw new \RuntimeException($client->getError());
}

Where to look first: open vendor/fergusean/nusoap/composer.json to confirm the autoload strategy, then skim lib/nusoap.php / lib/class.soap_client.php in the vendor tree for available methods (call, setEndpoint, setHeaders, setTimeout, setUseCurl, getError, debug_str). Because the package is unmaintained upstream, check its PHP compatibility against your app's PHP version before committing.

First use case: the canonical Laravel use is consuming a legacy SOAP/XML-RPC endpoint inside a queued job or a service class. Do a single call() inside php artisan tinker, dump $client->debug_str to see the raw request/response, and only then wire it into application code.

Implementation Patterns

Wrap it in a dedicated service class. Never let nusoap_client leak into controllers. Bind a per-endpoint client through the container:

// app/Services/Legacy/CustomerSoapClient.php
class CustomerSoapClient
{
    public function __construct(private array $config) {}

    public function getCustomer(int $id): array
    {
        $client = new \nusoap_client($this->config['wsdl'], 'wsdl');
        $client->setEndpoint($this->config['endpoint']); // override WSDL endpoint per env
        $client->setCredentials($this->config['user'], $this->config['pass']);
        $client->setTimeout(30);
        $client->setUseCurl(true);

        $result = $client->call('GetCustomer', ['id' => $id]);

        if ($client->getError()) {
            Log::warning('SOAP fault', [
                'error'   => $client->getError(),
                'request' => $client->request,
                'response'=> $client->response,
            ]);
            throw new SoapCallException($client->getError());
        }

        return $result;
    }
}

Register it in a service provider with singleton or scoped (one client per request is usually enough; clients are cheap to construct but expensive to reuse across credentials).

Config over hardcoding. Add config/services.php entries for WSDL URL, endpoint override, credentials, timeout, and verify_peer. This is essential because WSDL URLs often differ between sandbox and production, and NuSOAP will happily call the endpoint embedded in the WSDL if you forget setEndpoint.

Convert array results into DTOs immediately. NuSOAP returns nested associative arrays with inconsistent casing and sometimes wraps single elements differently from lists. Normalize once at the boundary, and the rest of your app stays SOAP-free.

For a SOAP server, use nusoap_server inside a route that bypasses CSRF and session middleware:

Route::post('/soap', function () {
    $server = new \nusoap_server();
    $server->configureWSDL('MyService', 'urn:myservice');
    $server->register('GetOrder', [...], [...], 'urn:myservice');
    $server->service(file_get_contents('php://input'));
})->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);

Note the use of php://input rather than $HTTP_RAW_POST_DATA (see below).

Use setHeaders for WS-Security / custom SOAP headers. NuSOAP has no built-in WSSE support; you build the <soap:Header> XML string yourself and pass it in. Wrap this in a small helper so the XML isn't duplicated.

Mock by constructor injection. Because your wrapper class takes config and constructs the nusoap_client internally, tests can subclass the wrapper or swap a fake implementation bound in the container. Do not try to mock \nusoap_client itself; it is not final but its property surface is too large to be useful.

Queues and retries. SOAP calls are blocking and can be slow. Push them to a job, use $tries/backoff, and translate the string error into an exception so Laravel's retry machinery kicks in.

Gotchas and Tips

  • Errors are strings, not exceptions. Every call must be followed by a getError() check, or you'll silently return false/null. Wrap this in your service class.
  • debug_str is a memory hog. It accumulates every request and response, including large XML payloads. Only enable it in non-production, or clear it after logging.
  • $HTTP_RAW_POST_DATA / HTTP_RAW_POST_DATA global. Old NuSOAP servers read the request body from a global that was removed in PHP 7. Always pass file_get_contents('php://input') explicitly to service().
  • PHP 8 compatibility. This fork tracks an old codebase: expect dynamic property deprecations, each()/create_function() remnants in older tags, and loose parameter handling. Pin the package version and test on your target PHP before shipping; if you're on PHP 8.2+, run the test suite with E_ALL and fix/suppress deprecations early.
  • WSDL caching. NuSOAP has optional WSDL caching (nusoap_wsdlcache) that writes to a directory. If your WSDL changes and your calls suddenly break, clear the cache directory or disable caching. In ephemeral containers, make sure the cache path is writable or disabled.
  • setEndpoint vs the WSDL endpoint. Without an explicit setEndpoint, NuSOAP uses the soap:address from the WSDL. In staging environments this often points to production — a classic incident. Always set it from config.
  • SSL/TLS options are not the usual Guzzle knobs. verify_peer is set through NuSOAP's transport options (or $client->setCurlOption(...) when using cURL), not Laravel's Http config. Prefer setUseCurl(true) because the cURL transport handles TLS and proxies more predictably than the raw socket transport.
  • Encoding surprises. NuSOAP defaults to ISO-8859-1 in places. If you have accented characters or emoji, verify the response is UTF-8 and pass 'utf-8' in the constructor or via setHttpEncoding where supported.
  • Array nesting is fragile. Complex types need the exact shape NuSOAP expects: often an array of arrays, sometimes with xsi:type annotations. When in doubt, dump $client->request and compare to a working SoapUI request.
  • LGPL-2.1 license. Fine for internal tools and SaaS where you don't distribute the library, but if you ship a proprietary desktop/on-prem product that links it, review your obligations with legal.
  • Consider alternatives. The PHP soap extension is faster and better supported if it's enabled; phpro/soap-client generates typed clients from a WSDL and integrates well with Laravel. Reach for NuSOAP specifically when the extension isn't available, when you need its WSDL-generation server side, or when you're maintaining a legacy integration — not for new greenfield SOAP clients.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums