php-soap/xml
php-soap/xml is a lightweight XML library for PHP focused on SOAP. It offers namespace-aware parsing and generation so you can build, inspect, and transform SOAP envelopes and XML payloads through a small, predictable API. Designed for dependable XML handling in PHP applications.
What this package is. php-soap/xml is a thin, single-purpose XML wrapper used by the php-soap family of packages (notably php-soap/engine and its transports/decoders) to parse SOAP envelopes and manipulate XML without hard-coupling to ext-soap. It is a library, not a product: it has no service surface, no configuration, no runtime daemon, and no opinion about HTTP or transport.
Architecture fit. Good fit only as an internal building block. In a Laravel codebase it belongs underneath a SOAP client abstraction — either the php-soap engine stack or a home-grown client — where it handles envelope construction, namespace-aware element access, and response traversal. It is a poor fit as a direct dependency of application/domain code; if feature code is calling this wrapper, the abstraction boundary is wrong.
Integration feasibility. Mechanically trivial: Composer install, ext-dom present on virtually every PHP image, MIT license, no native extensions to compile, no credentials or network calls. The realistic decision is not "can we install it" but "should this be a direct requirement" — in most cases it should arrive transitively via the engine, pinned in composer.lock.
Technical risk.
^ ranges and a lockfile.Key questions to put to the maintainer (or answer by reading the source).
LIBXML_NONET, no entity substitution), and is that configurable?ext-dom versions are in the CI matrix?php-soap/engine, and does the engine expose it or hide it?Stack fit. Excellent fit for a Laravel monolith or modular monolith that must talk to a small number of legacy SOAP services (payments, ERP, government gateways, shipping). Laravel's PSR-18/PSR-7 HTTP client story and Guzzle/Symfony HTTP client both slot beneath a php-soap transport, so the XML layer is agnostic to how requests are actually sent. It also fits cleanly into queue workers and console commands, which is where most SOAP integrations actually run.
Migration path. Three realistic entry points, in ascending order of effort:
php-soap/engine + a PSR-18 transport; php-soap/xml comes along transitively. Lowest effort, no legacy surface.ext-soap's SoapClient — a real migration, not a swap. SoapClient gives you WSDL-driven class mapping, __soapCall, and typed results for free; this package gives you none of that. Expect to hand-write or generate request/response DTOs and mapping code. Budget per endpoint, not per project.spatie/array-to-xml, hand-rolled DOMDocument, SimpleXMLElement) — straightforward, but only worth doing if you are already consolidating on the php-soap stack. Otherwise you are trading one small wrapper for another.Compatibility. Confirm PHP ^8.1+ (match your Laravel 10/11/12 floor), ext-dom enabled in every image including CI and production, and libxml version parity between local Docker and production — libxml differences are a classic source of "passes locally, fails in prod" XML bugs. Check that nothing else in the dependency graph pins an incompatible php-soap major.
Sequencing.
PaymentGatewayClient interface so the XML library never leaks into application code. This is the single most important step for reversibility.SOAPAction).Anti-pattern to avoid. Adding this as a direct dependency and calling it from controllers, jobs, and models. That converts a cheap-to-replace transitive library into an expensive-to-replace implicit framework.
Maintenance. Very low steady-state cost — no daemon, no migrations, no config, no scheduled work. The real maintenance obligation is version hygiene: this library will bump majors faster than Laravel will, and each bump needs a Composer constraint review and a regression run over the SOAP contract tests. Estimate a few hours per year, plus the cost of the occasional engine upgrade. Assign a named owner; an unowned transitive dependency is how you discover a break during an incident.
Support. Community-only: GitHub issues, no SLA, no vendor to escalate to. For a business-critical payment or ERP integration that is a genuine gap. The compensating control is the wrapper boundary described above — if support evaporates, you swap the implementation behind your interface without touching callers. Have an explicit "fork and vendor" runbook written before you need it, including who can publish to your private Packagist/Satis mirror.
Scaling. SOAP/XML is CPU- and memory-bound, not IO-bound. A DOM-based wrapper materializes the whole document, so memory scales with payload size — fine for typical 10–500 KB responses, a problem for multi-megabyte attachments or bulk exports. Throughput scales horizontally with PHP-FPM/queue workers, so capacity planning is ordinary. Watch for: response payload spikes from upstream (a misbehaving ERP returning a 50 MB report), and the latency cliff when an upstream SOAP service degrades — enforce timeouts and circuit breaking at the HTTP layer, not here.
Failure modes to instrument and alert on.
"0.00" becoming falsy, or leading zeros in identifiers being stripped.Log the correlation ID, endpoint, HTTP status, and a truncated body at the boundary; that is where nearly all SOAP incidents are diagnosed.
Ramp-up. Low for anyone comfortable with DOMDocument; the abstraction is thin and leaky by design, so developers will hit raw DOM semantics quickly. A mid-level Laravel developer is productive in half a day for straightforward calls; a day or two to be genuinely safe with namespaces, fault handling, and WS-Security. The larger ramp-up cost is organizational: your team must understand the SOAP contract itself, and this library does nothing to help with that.
Bottom line for a TPM. Low-risk, low-cost, low-visibility dependency that is worth adopting only as part of the php-soap stack and only behind a domain interface you control. Approve as a transitive dependency with a locked version and a named owner; treat a direct dependency as a deliberate architectural decision requiring the same wrapper discipline you would apply to any external SDK.
How can I help you explore Laravel packages today?