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

Packagegenerator Laravel Package

wsdltophp/packagegenerator

wsdltophp/packagegenerator turns WSDL files and XML schemas into complete PHP packages, generating classes, models, and SOAP client code so you can integrate web services quickly without hand-writing repetitive boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the generator as a dev dependency (it emits code you commit or build in CI; it isn't a runtime dependency):

composer require --dev wsdltophp/packagegenerator
php -d memory_limit=-1 vendor/bin/wsdltophp generate:package \
  --urlorpath="https://example.com/service?wsdl" \
  --destination="app/Services/BillingApi" \
  --composer-name="acme/billing-api-client" \
  --namespace="App\\Services\\BillingApi\\"

Where to look first:

  • vendor/bin/wsdltophp generate:package --help — options drift between releases; trust --help over blog posts.
  • The generated Struct/, EnumType/, ServiceType/, and Client.php (or Service class) directories — this is the actual API surface you'll code against.
  • The generated README.md in the output directory — it documents generated classes and typical usage per WSDL.

First use case: Pick one operation (e.g., GetCustomer) and one response struct. Instantiate the generated client, call the operation, dump ->getResult(), and confirm the returned object graph before scaling up. Do not try to wire all operations at once — WSDLs with 200+ types will bury you.

Prerequisites: ext-soap must be enabled (this is the single most common "it doesn't work" cause). PHP 8.x recommended; check the composer constraint for exact minimum.

Implementation Patterns

Commit generated code, don't regenerate per deploy. The output is deterministic given a WSDL, but WSDLs change without notice on many providers. Commit the generated tree, review the diff on regeneration, and treat regeneration as a deliberate, reviewed change.

Wrap the generated client in a Laravel service. Never call the generated Client directly from controllers or jobs. Wrap it:

// app/Services/BillingApi/BillingGateway.php
final class BillingGateway
{
    public function __construct(private \App\Services\BillingApi\ServiceType\Billing $client) {}

    public function getCustomer(string $id): ?Customer
    {
        try {
            $resp = $this->client->getCustomer(new GetCustomer($id));
            return $resp->getResult();
        } catch (\SoapFault $e) {
            throw new BillingApiException($e->getMessage(), previous: $e);
        }
    }
}

Bind it in a service provider and inject the interface into jobs/listeners.

Map generated structs to your domain at the boundary. The generated classes are a transport concern. Convert a generated Customer struct into your own DTO or Eloquent model in the gateway, so the rest of your app never depends on the vendor namespace. This also insulates you if the WSDL changes.

Put credentials/options in config/services.php and pass them to the generated client's constructor (login, password, trace, connection_timeout, etc.). The generated client exposes the standard SoapClient options array — reuse it.

Queue long calls. SOAP calls are synchronous and often slow. Dispatch a job (ShouldQueue, $timeout set) that resolves the gateway from the container. Use $this->release() with backoff for transient failures.

Test against a fake gateway, not a fake SoapClient. Because the gateway interface is yours, you mock it in feature tests. For integration tests against a recorded WSDL, point the client at a local .wsdl file (see gotchas) with wsdl_cache disabled.

CI regeneration check (optional but valuable): a scheduled job regenerates into a temp dir and diffs against the committed tree. Any diff means the upstream WSDL changed and needs review.

Gotchas and Tips

  • ext-soap is required and not always present. Many Docker/CI images ship without it. Add docker-php-ext-install soap or apt-get install php-soap. Check in a health/console command if the integration is core.
  • No default timeouts. SoapClient will happily hang forever. Always set connection_timeout (and default_socket_timeout via ini_set if needed). Wrap calls in a queue with a hard timeout.
  • Cache the WSDL. Set wsdl_cache options or fetch a copy of the WSDL to storage/app/wsdls/ and generate/client against the local file. This makes generation reproducible and insulates you from the vendor being down mid-deploy.
  • --composer-name and autoloading. If you generate inside app/, the classes are autoloaded by your app's PSR-4 — do not add a second autoload entry. If you generate into a separate packages/ directory, add the PSR-4 mapping explicitly.
  • Generated code is not editable, but it is verbose. Expect hundreds of files. Don't run static analysis (PHPStan/Psalm) over the output unless you exclude it; add the directory to your phpstan.neon excludePaths and to .gitattributes/formatter ignores. Do run the formatter/linter on your wrappers, not the generated tree.
  • Namespacing collisions. Generated names sometimes clash with Laravel/Symfony classes (e.g., Request, Response, Header). Always reference generated classes fully-qualified or via the wrappers — never use them at the top of a file that also touches Laravel types.
  • WS-Security / custom headers are not always auto-wired. If the WSDL doesn't advertise them, you must inject __soapCall headers manually. Check generated classes for a setSoapHeader/__setSoapHeaders path or subclass the client and override __doRequest.
  • Enums vs. strings. Older WSDL tooling emits string constants; newer generates EnumType\* classes. Be explicit about which you're passing — passing a raw string where an enum object is expected yields confusing SoapFaults from the server, not the client.
  • Nullable/optional structs. Generated getters may return null for fields absent in the response. Guard every access; a missing getX() result is a runtime Error, not a SoapFault.
  • Regeneration strategy. Pin the exact generator version in composer.json as --dev. A minor generator bump can change method signatures of the generated tree. Upgrade deliberately and diff.
  • Extension point: the generator supports custom templates (--struct-* options / a templates dir). If you need every struct to implement a common interface or extend a base class, do it here rather than post-processing files — post-processing is fragile.
  • Debugging: enable trace => 1 in the client options and inspect __getLastRequest() / __getLastResponse(). This is the fastest way to see what the vendor actually requires when the WSDL is misleading.
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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle