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

Wsdl2Php Generator Cli Bundle Laravel Package

venture-oak-labs/wsdl2php-generator-cli-bundle

Symfony bundle adding console commands for the wsdl2php-generator library, so you can turn WSDL/SOAP definitions into PHP classes from the CLI. Handy for SOAP integrations; requires Symfony Console and the underlying generator package.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this as a build-time code generator, not a runtime dependency. It is a Symfony bundle whose only job is to register a console command that runs wsdl2phpgenerator — the library that turns a WSDL file into PHP SOAP client classes. Laravel does not load Symfony bundles, so in practice you will get more mileage by depending on the underlying generator and wrapping it in an Artisan command than by trying to mount the bundle.

Minimal path:

  1. composer require --dev venture-oak-labs/wsdl2php-generator-cli-bundle (or just wsdl2phpgenerator/wsdl2phpgenerator if you only want the library).
  2. Open vendor/venture-oak-labs/wsdl2php-generator-cli-bundle/ and read the bundle class and its Command/ directory first. That is the whole surface area — there is no config tree, no service aliases, and no Laravel auto-discovery. Note the command name and constructor arguments.
  3. Because Laravel will not boot the bundle, create your own command:
php artisan make:command GenerateSoapClient
// app/Console/Commands/GenerateSoapClient.php
protected $signature = 'soap:generate
    {wsdl : Path or URL to the WSDL}
    {--namespace=App\\Soap\\Generated : Target namespace}
    {--out=app/Soap/Generated : Output directory}';

public function handle()
{
    $generator = new \Wsdl2PhpGenerator\Generator();
    $generator->generate(new \Wsdl2PhpGenerator\Config([
        'inputFile'      => $this->argument('wsdl'),
        'outputDir'      => base_path($this->option('out')),
        'namespaceName'  => $this->option('namespace'),
        'constructorParamsDefaultToNull' => true,
    ]));
}
  1. First real use case: you are consuming a partner/vendor SOAP API (payments, shipping, government gateways). Drop their WSDL into storage/app/wsdl/, run php artisan soap:generate storage/app/wsdl/vendor.wsdl, commit the generated classes under app/Soap/Generated/. From that point on the generator is irrelevant until the vendor ships a new WSDL.

First thing to sanity-check before committing to the approach: the underlying generator's PHP version constraint. It historically lags; on PHP 8.2+ you may need composer require with --ignore-platform-req or a fork.

Implementation Patterns

Generate once, commit, review the diff. The value of this package is the deterministic transformation WSDL → classes. Run it in CI on a branch, diff the output, and open a PR when the vendor WSDL changes. Do not run generation at deploy time — you lose reproducibility and the WSDL URL becomes a production dependency.

Separate the generated layer from your domain. Generated classes are dumb DTOs and a giant Service proxy. Wrap them:

// app/Services/Shipping/ShippingGateway.php
final class ShippingGateway
{
    public function __construct(private \App\Soap\Generated\ShippingService $client) {}

    public function quote(QuoteRequest $request): Quote
    {
        try {
            $res = $this->client->getQuote($request->toSoap());
        } catch (\SoapFault $e) {
            throw new ShippingUnavailable($e->getMessage(), previous: $e);
        }
        return Quote::fromSoap($res);
    }
}

Bind the generated client in a service provider with credentials pulled from config:

// app/Providers/SoapServiceProvider.php
$this->app->singleton(ShippingService::class, fn () => new ShippingService([
    'location'   => config('services.shipping.wsdl'),
    'login'      => config('services.shipping.user'),
    'password'   => config('services.shipping.password'),
    'trace'      => app()->isLocal(),   // capture envelopes in dev only
    'exceptions' => true,
]));

Drive generation from config, not CLI flags. Keep a config/soap.php with a map of WSDL sources and target namespaces, and have your command iterate over it. That gives you php artisan soap:generate --all for regeneration and one place to look when a namespace or output path drifts.

Testing. Never mock the generated client directly — it is a concrete class with dozens of methods. Instead:

  • Test your ShippingGateway against a fake HTTP transport if the underlying client supports one, or
  • Bind a hand-written ShippingGateway interface to an in-memory implementation in TestCase, and only exercise the real generated client in a tagged @group integration suite.
  • Assert on the request envelope rather than on the SOAP response ($client->__getLastRequest() when trace is on) — that is what usually breaks when a WSDL changes.

Version pinning. After the first successful generation, record the WSDL hash in a comment or a small app/Soap/Generated/.version file. Your command can refuse to run if the WSDL differs unless --force is passed — this prevents accidental churn from a vendor silently publishing a new WSDL.

Gotchas and Tips

  • This is not a Laravel package. There is no service provider, no bundle.php, no extra.laravel. composer require will succeed but nothing will happen. You either register the Symfony bundle manually (painful, requires a minimal Symfony kernel) or, as above, skip the bundle and use the library. Given 0 dependents and 2 stars, assume no Laravel integration exists or is planned.
  • Generated code style is dated. Expect PSR-0-ish class names, no strict types, and inconsistent namespacing unless you pass namespaceName. Run php-cs-fixer or Pint over the output directory as a post-step, or exclude it from style checks entirely — do not hand-fix generated files.
  • Output directory gets overwritten. Never put custom logic under app/Soap/Generated/. If you need to extend a generated class, subclass it in a sibling directory and reference the subclass.
  • WSDL fetching needs network at generate time. Vendor endpoints frequently require mTLS, basic auth, or IP allowlisting. Download the WSDL manually, commit it to storage/app/wsdl/, and pass the file path. You get reproducible builds and no CI firewall issues.
  • Requires the soap PHP extension for the generated clients to run (not for generation). Check php -m | grep soap in every environment and in your composer.json ext-soap requirement. This trips up containerised setups constantly.
  • trace and exceptions options matter for debugging. With trace => true you get __getLastRequest() / __getLastResponse() on the client — log those envelopes into a dedicated channel when you catch a SoapFault. With exceptions => false (the default) you get silent failures; always set exceptions => true.
  • Large WSDLs generate enormous trees. Government and banking APIs can produce hundreds of classes for types you will never use. There is no filtering option in the CLI — if it becomes a problem, generate into a separate package and only use the handful of classes you need, or hand-roll a slimmer client with ext-soap directly.
  • Debugging generation failures is opaque: the CLI emits generic exceptions. Run the generator from tinker or a standalone script where you can dd($e->getTrace()), and validate the WSDL first with xmllint --noout — malformed imports and relative schemaLocation entries are the usual culprits.
  • Extension points are essentially nil. The bundle exposes no events, no config, no tagged services. If you need to customise generation (custom type mapping, naming strategies), fork or wrap the library — do not expect the bundle to grow hooks. Treat it as a thin, disposable shim and keep your investment in the wrapper command and gateway layer, which are yours to maintain.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log