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

Packagebase Laravel Package

wsdltophp/packagebase

Base library for PHP packages generated from WSDL files by wsdltophp/packagegenerator. It supplies shared runtime utilities, helpers, and common behavior so generated SOAP client code stays lean, consistent, and easier to maintain.

Deep Wiki
Context7

Getting Started

You almost never install wsdltophp/packagebase by hand — it arrives as a transitive dependency of a client generated by wsdltophp/packagegenerator. Treat this repo as the runtime contract your generated SOAP client depends on, and read it when you need to know exactly what a generated class can do.

Minimal path to first use:

# 1. Generate a client package from a WSDL (usually via the generator, not this repo)
composer require --dev wsdltophp/packagegenerator
vendor/bin/generate.phar generate:package --urlorpath=/path/to/service.wsdl --composer-name=vendor/api-client

# 2. In the generated package, packagebase is a normal require
composer require wsdltophp/packagebase

First things to read, in order:

  1. The generated Settings.php — it wires AbstractSoapClientBase options (WSDL, location, uri, classmap, trace, cache).
  2. WsdlToPhp\PackageBase\AbstractSoapClientBase — the object your ServiceType\* classes extend.
  3. The base class your generated StructType\* classes extend (AbstractStructBase on v3, AbstractStruct/AbstractStructBase on v4 depending on generator version) — it defines __toArray, jsonSerialize, and property access.
  4. AbstractArrayType, AbstractEnumType, AbstractSimpleType — the collection/enum/scalar plumbing generated code delegates to.

First real use case: build a struct, call an operation, inspect the result.

use Vendor\ApiClient\ServiceType\Search;
use Vendor\ApiClient\StructType\SearchRequestType;

$svc = new Search();
$req = new SearchRequestType();
$req->setQuery('widgets');

$result = $svc->Search($req);        // returns a generated struct or throws SoapFault
if ($result === false) {
    throw new \RuntimeException($svc->getLastError());
}
print_r($result->__toArray());

Implementation Patterns

Wrap generated services, don't call them from controllers. AbstractSoapClientBase caches a single \SoapClient instance (getSoapClient()), so long-lived processes share the connection. Inject the generated ServiceType\* class into a repository/adapter and expose domain methods — this isolates the noisy generated API (setFoo, getFoo, __toArray) from application code.

Hydrate structs with arrays for readability. All generated structs accept associative arrays through their setters, and nested structs are auto-constructed where the WSDL declares them:

$req = new SearchRequestType([
    'Query'   => 'widgets',
    'Filters' => ['Category' => 'tools'], // nested StructType
]);

Reuse the base struct for JSON/serialisation boundaries. __toArray() and jsonSerialize() come from the base class and are the only stable way to reach property values without knowing every getter. For anything beyond the default shape, subclass the generated struct and override jsonSerialize() — never edit generated files.

final class SearchRequestType extends \Vendor\ApiClient\StructType\SearchRequestType
{
    public function jsonSerialize(): array
    {
        $data = parent::jsonSerialize();
        unset($data['InternalFlag']);
        return $data;
    }
}

Centralise SOAP client options. Rather than mutating generated Settings, extend AbstractSoapClientBase in a project-level base, or set options once after construction:

$svc = new Search();
$svc->setSoapClientOption(SOAP_1_2, 'soap_version');
$svc->setSoapClientOption('https://proxy.internal/soap', 'proxy_host');
$svc->setSoapClientOption(120, 'connection_timeout');

Attach custom SOAP headers at the service level. Generated structs for headers exist, but you can also push raw \SoapHeader objects when a WSDL doesn't define them:

$svc->getSoapClient()->__setSoapHeaders(new \SoapHeader('urn:auth', 'ApiKey', $key));

Enums and simple types. Generated enum classes expose getValidValues() and validate via setValue(); use them as guards at the edge of your integration rather than scattering strings.

if (!SearchMode::valueIsValid($mode)) {
    throw new \InvalidArgumentException("Unknown search mode: {$mode}");
}
$req->setMode(new SearchMode($mode));

Debugging pattern for every integration. Wrap calls so getLastRequest/getLastResponse/getLastRequestHeaders can be logged on failure — this is the single highest-value feature of AbstractSoapClientBase and the main reason to keep trace => true in staging.

try {
    return $svc->Search($req);
} catch (\SoapFault $e) {
    $logger->error('SOAP fault', [
        'fault'    => $e->getMessage(),
        'request'  => $svc->getLastRequest(),
        'response' => $svc->getLastResponse(),
    ]);
    throw $e;
}

Gotchas and Tips

  • Generated code is throwaway. Every regeneration overwrites StructType/, ServiceType/, EnumType/, etc. Put all custom behaviour in subclasses, or configure PackageGenerator's "extends" option so it generates classes extending your base classes from the start.
  • Version coupling is strict. PackageGenerator v3 emits clients against packagebase v3 (AbstractStructBase, AbstractStructArrayBase); PackageGenerator v4+ targets packagebase v4 with renamed/consolidated bases. Match them or generated classes will fail with "class not found"/signature errors. Pin the generator version in composer.json ("wsdltophp/packagegenerator": "^4") and regenerate deliberately.
  • getLastRequest() returns null unless trace => true. Confirm Settings::getSoapClientOption('trace') is truthy before relying on it — otherwise you get silent nulls during an incident. Keep trace on in staging, off (or sampled) in production.
  • Distinguish SoapFault from transport errors. getLastError() covers connection/DNS/HTTP failures where the client returns false instead of throwing; SoapFault covers server-side faults, which often arrive with HTTP 500 too. Check both paths.
  • WSDL caching bites in CI and containers. Default SoapClient caching writes to wsdl-* files under sys_get_temp_dir(); stale caches produce "failed to load external entity" or outdated classmap errors. Use AbstractSoapClientBase::WSDL_CACHE_NONE (or WITHOUT_WSDL_CACHE) in tests/CI, and warm the cache in a deploy step if cold-start latency matters.
  • PHP 8.2+ dynamic properties. Do not assign $struct->Foo = 'x'; use setFoo(). The base structs expose properties via interfaces/magic access in older versions, and relying on that will emit deprecation warnings or break on newer runners.
  • Non-WSDL mode needs explicit location/uri. If you generate without a WSDL (or point at a WSDL behind auth you don't have), set both location and uri on the service before calling, or every call fails with "SOAP-ERROR: Parsing WSDL".
  • Nested array-of-struct wrapping. AbstractArrayType expects values of the declared item type. Passing plain arrays into a property typed as FooArrayType won't auto-wrap in every generated version — construct the generated array type (new FooArrayType($items)) or the class map will silently mis-serialise.
  • Connection reuse in workers. AbstractSoapClientBase::getSoapClient() memoises the \SoapClient. Under long-running workers (Octane/Horizon) a single cached client will hold a stale connection and any per-request setSoapClientOption changes won't re-init. Instantiate service classes per request/job, or reset between messages.
  • Extension points to know. Override initSoapClient() (older bases) or getSoapClient() (newer bases) in a project-level abstract service to inject middleware, custom classmap, or logging around __doRequest. This is the sanctioned hook; avoid monkey-patching \SoapClient.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager