PHPackages                             php-soap/psr18-transport - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. php-soap/psr18-transport

ActiveLibrary[HTTP &amp; Networking](/categories/http)

php-soap/psr18-transport
========================

PSR-18 HTTP Client transport for SOAP

2.1.0(2mo ago)183.9M↓47.1%5[1 issues](https://github.com/php-soap/psr18-transport/issues)13MITPHPPHP ~8.4.0 || ~8.5.0CI passing

Since Jul 8Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/php-soap/psr18-transport)[ Packagist](https://packagist.org/packages/php-soap/psr18-transport)[ Fund](https://opencollective.com/php-soap)[ RSS](/packages/php-soap-psr18-transport/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (10)Dependencies (54)Versions (21)Used By (13)

PSR-18 SOAP Transport
=====================

[](#psr-18-soap-transport)

This transport allows you to send SOAP requests over a PSR-18 HTTP client implementation. You can use any client you want, going from curl, guzzle, httplug, symfony/http-client, ... It allows you to get full control over the HTTP layer, making it possible to e.g. overcome some well-known issues in `ext-soap`. This package can best be used together with a [SOAP driver](https://github.com/php-soap/engine) that handles data encoding and decoding.

Want to help out? 💚
===================

[](#want-to-help-out-)

- [Become a Sponsor](https://github.com/php-soap/.github/blob/main/HELPING_OUT.md#sponsor)
- [Let us do your implementation](https://github.com/php-soap/.github/blob/main/HELPING_OUT.md#let-us-do-your-implementation)
- [Contribute](https://github.com/php-soap/.github/blob/main/HELPING_OUT.md#contribute)
- [Help maintain these packages](https://github.com/php-soap/.github/blob/main/HELPING_OUT.md#maintain)

Want more information about the future of this project? Check out this list of the [next big projects](https://github.com/php-soap/.github/blob/main/PROJECTS.md) we'll be working on.

Prerequisites
=============

[](#prerequisites)

Choosing what HTTP client you want to use. This package expects some PSR implementations to be present in order to be installed:

- PSR-7: `psr/http-message-implementation` like `nyholm/psr7` or `guzzlehttp/psr7`
- PSR-17: `psr/http-factory-implementation` like `nyholm/psr7` or `guzzlehttp/psr7`
- PSR-18: `psr/http-client-implementation` like `symfony/http-client` or `guzzlehttp/guzzle`

Installation
============

[](#installation)

```
composer require php-soap/psr18-transport
```

Usage
-----

[](#usage)

```
use Http\Client\Common\PluginClient;
use Soap\Engine\SimpleEngine;
use Soap\Psr18Transport\Psr18Transport;

$engine = new SimpleEngine(
    $driver,
    $transport = Psr18Transport::createForClient(
        new PluginClient(
            $psr18Client,
            [...$middleware]
        )
    )
);
```

Middleware
----------

[](#middleware)

This package provides some middleware implementations for dealing with some common SOAP issues.

### Wsdl\\DisableExtensionsMiddleware

[](#wsdldisableextensionsmiddleware)

PHP's ext-soap implementation do not support `wsdl:required` attributes since there is no SOAP extension mechanism in PHP. You will retrieve this exception: "\[SoapFault\] SOAP-ERROR: Parsing WSDL: Unknown required WSDL extension" when the WSDL does contain required SOAP extensions.

This middleware can be used to set the "wsdl:required" property to false when loading the WSDL so that you don't have to change the WSDL on the server.

**Usage**

```
use Http\Client\Common\PluginClient;
use Soap\Psr18Transport\Middleware\Wsdl\DisableExtensionsMiddleware;

$wsdlClient = new PluginClient(
    $psr18Client,
    [
        new DisableExtensionsMiddleware(),
    ]
);
```

### Wsdl\\DisablePoliciesMiddleware

[](#wsdldisablepoliciesmiddleware)

PHP's ext-soap client does not support the [Web Services Policy Framework](http://schemas.xmlsoap.org/ws/2004/09/policy/) attributes since there is no such support in PHP. You will retrieve this exception: "\[SoapFault\] SOAP-ERROR: Parsing WSDL: Unknown required WSDL extension ''" when the WSDL does contains WS policies.

This middleware can be used to remove all UsingPolicy and Policy tags on the fly so that you don't have to change the WSDL on the server.

**Usage**

```
use Http\Client\Common\PluginClient;
use Soap\Psr18Transport\Middleware\Wsdl\DisablePoliciesMiddleware;

$wsdlClient = new PluginClient(
    $psr18Client,
    [
        new DisablePoliciesMiddleware(),
    ]
);
```

### RemoveEmptyNodesMiddleware

[](#removeemptynodesmiddleware)

Empty properties are converted into empty nodes in the request XML. If you need to avoid empty nodes in the request xml, you can add this middleware.

**Usage**

```
use Http\Client\Common\PluginClient;
use Soap\Psr18Transport\Middleware\RemoveEmptyNodesMiddleware;

$httpClient = new PluginClient(
    $psr18Client,
    [
        new RemoveEmptyNodesMiddleware()
    ]
);
```

### PromoteNamespacesMiddleware

[](#promotenamespacesmiddleware)

The [`php-soap/encoding`](https://github.com/php-soap/encoding) package encodes and decodes SOAP payloads isomorphically: every encoded element declares its own `xmlns:*` prefixes locally, so the same fragment produces the same XML whether it lives at the root of a document or deep inside another element. That is valid XML, but some SOAP servers enforce via XSD that all namespaces are declared on the envelope itself and reject payloads with descendant-level declarations (e.g. Microsoft Business Central).

Plug this middleware in between the encoder and the wire to rewrite the outgoing request so that every prefixed `xmlns:*` declaration found on a descendant is hoisted to the envelope, keeping the original prefix names intact. Default namespaces (`xmlns="..."`) and prefixes that conflict with a declaration already on the envelope are left untouched.

**Usage**

```
use Http\Client\Common\PluginClient;
use Soap\Psr18Transport\Middleware\PromoteNamespacesMiddleware;

$httpClient = new PluginClient(
    $psr18Client,
    [
        new PromoteNamespacesMiddleware()
    ]
);
```

### SoapHeaderMiddleware

[](#soapheadermiddleware)

Attaches multiple SOAP headers to the request before sending the SOAP envelope.

**Usage**

```
use Http\Client\Common\PluginClient;
use Soap\Psr18Transport\Middleware\RemoveEmptyNodesMiddleware;
use Soap\Xml\Builder\Header\Actor;
use Soap\Xml\Builder\Header\MustUnderstand;
use Soap\Xml\Builder\SoapHeader;

$httpClient = new PluginClient(
    $psr18Client,
    [
        new SoapHeaderMiddleware(
            new SoapHeader(
                $tns,
                'x:Auth',
                children(
                    namespaced_element($tns, 'x:user', value('josbos')),
                    namespaced_element($tns, 'x:password', value('topsecret'))
                )
            ),
            new SoapHeader($tns, 'Acting', Actor::next()),
            new SoapHeader($tns, 'Understanding', new MustUnderstand())
        )
    ]
);
```

More information on the SoapHeader configurator can be found in [php-soap/xml](https://github.com/php-soap/xml#soapheaders).

### HTTPlug middleware

[](#httplug-middleware)

This package includes [all basic plugins from httplug](https://docs.php-http.org/en/latest/plugins/). You can load any additional plugins you want, like e.g. [the logger plugin](https://github.com/php-http/logger-plugin).

**Examples**

```
use Http\Client\Common\Plugin\AuthenticationPlugin;
use Http\Client\Common\Plugin\BaseUriPlugin;
use Http\Client\Common\Plugin\LoggerPlugin;
use Http\Message\Authentication\BasicAuth;

$httpClient = new PluginClient(
    $psr18Client,
    [
        new BaseUriPlugin($baseLocation),
        new AuthenticationPlugin(new BasicAuth($_ENV['user'], $_ENV['pass'])),
        new LoggerPlugin($psrLogger),
    ]
);
```

### Writing your own middleware

[](#writing-your-own-middleware)

We use httplug for its plugin system. You can create your own middleware by [following their documentation](https://docs.php-http.org/en/latest/plugins/build-your-own.html).

Authentication
--------------

[](#authentication)

You can add authentication to both the WSDL fetching and SOAP handling part. For this, we suggest you to use the default [httplug authentication providers](https://docs.php-http.org/en/latest/message/authentication.html).

### NTLM

[](#ntlm)

Adding NTLM authentication requires you to use a `curl` based PSR-18 HTTP Client. On those clients, you can set following options: `[CURLOPT_HTTPAUTH => CURLAUTH_NTLM, CURLOPT_USERPWD => 'user:pass']`. Clients like guzzle and symfony/http-client also support NTLM by setting options during client configuration.

Dealing with XML
----------------

[](#dealing-with-xml)

When writing custom SOAP middleware, a frequent task is to transform the request or response XML into a slight variation. This package provides some shortcut tools around [php-soap/xml](https://github.com/php-soap/xml) to make it easier for you to deal with XML.

**Example**

```
use Http\Client\Common\Plugin;
use Http\Promise\Promise;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Soap\Psr18Transport\Xml\XmlMessageManipulator;
use VeeWee\Xml\Dom\Document;

class SomeMiddleware implements Plugin
{
    public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise
    {
        $request = (new XmlMessageManipulator)(
            $request,
            fn (Document $document) => $document->manipulate(
                doSomethingWithRequestXml()
            )
        );

        return $next($request)
            ->then(function (ResponseInterface $response): ResponseInterface {
                return (new XmlMessageManipulator)(
                    $response,
                    fn (Document $document) => $document->manipulate(
                        doSomethingWithResponseXml()
                    )
                );
            });
    }
}
```

Loading WSDL with PSR-18 clients
--------------------------------

[](#loading-wsdl-with-psr-18-clients)

For loading WSDL's, you might want to use a PSR-18 client to do the hard HTTP work. This allows you for advances setups in which the WSDL is put behind basic authentication. This package provides a PSR-18 [WSDL loader](https://github.com/php-soap/wsdl#wsdl-loader) that can be used to load HTTP locations with your favourite HTTP client. It can be used in combinations with for example the WSDL loaders from the [php-soap/ext-soap-engine](https://github.com/php-soap/ext-soap-engine).

### Psr18Loader

[](#psr18loader)

**Examples**

```
use Http\Client\Common\PluginClient;
use Soap\Psr18Transport\Wsdl\Psr18Loader;
use Soap\Wsdl\Loader\FlatteningLoader;

$loader = Psr18Loader::createForClient(
    $wsdlClient = new PluginClient(
        $psr18Client,
        [...$middleware]
    )
);

// If you want to flatten all imports whilst using this PSR-18 loader:
$loader = new FlatteningLoader($loader);

$payload = $loader('http://some.wsdl');
```

*NOTE:* If you want to flatten the imports inside the WSDL, you'll have to combine this loader with the the [FlatteningLoader](https://github.com/php-soap/wsdl#flatteningloader).

Async SOAP calls
----------------

[](#async-soap-calls)

Since PHP 8.1, fibers are introduced to PHP. This means that you can use any fiber based PSR-18 client in order to send async calls.

Here is a short example for `react/http` in combination with `react/async`.

```
composer require react/async veewee/psr18-react-browser
```

*(There currently is no official fiber based PSR-18 implementation of either AMP or ReactPHP. Therefore, [a small bridge can be used intermediately](https://github.com/veewee/psr18-react-browser))*

Usage:

```
use Http\Client\Common\PluginClient;
use Soap\Engine\SimpleEngine;
use Soap\ExtSoapEngine\ExtSoapDriver;
use Soap\ExtSoapEngine\ExtSoapOptions;
use Soap\ExtSoapEngine\Wsdl\TemporaryWsdlLoaderProvider;
use Soap\Psr18Transport\Psr18Transport;
use Soap\Psr18Transport\Wsdl\Psr18Loader;
use Soap\Wsdl\Loader\FlatteningLoader;
use Veewee\Psr18ReactBrowser\Psr18ReactBrowserClient;
use function React\Async\async;
use function React\Async\await;
use function React\Async\parallel;

$asyncHttpClient = Psr18ReactBrowserClient::default();
$engine = new SimpleEngine(
    ExtSoapDriver::createFromClient(
        $client = AbusedClient::createFromOptions(
            ExtSoapOptions::defaults('http://www.dneonline.com/calculator.asmx?wsdl', [])
                ->disableWsdlCache()
        )
    ),
    $transport = Psr18Transport::createForClient(
        new PluginClient(
            $asyncHttpClient,
            [...$middleware]
        )
    )
);

$add = async(fn ($a, $b) => $engine->request('Add', [['intA' => $a, 'intB' => $b]]));
$addWithLogger = fn ($a, $b) => $add($a, $b)->then(
    function ($result) use ($a, $b) {
        echo "SUCCESS {$a}+{$b} = ${result}!" . PHP_EOL;
        return $result;
    },
    function (Exception $e) {
        echo 'ERROR: ' . $e->getMessage() . PHP_EOL;
    }
);

$results = await(parallel([
    fn() => $addWithLogger(1, 2),
    fn() => $addWithLogger(3, 4),
    fn() => $addWithLogger(5, 6)
]));

var_dump($results);
```

###  Health Score

64

—

FairBetter than 99% of packages

Maintenance85

Actively maintained with recent releases

Popularity53

Moderate usage in the ecosystem

Community26

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor1

Top contributor holds 94.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~116 days

Recently: every ~46 days

Total

16

Last Release

71d ago

Major Versions

v0.1.0 → v1.0.02021-09-24

1.8.0 → 2.0.02026-03-27

PHP version history (6 changes)v0.1.0PHP ^8.0

v1.3.0PHP ~8.1.0 || ~8.2.0

1.5.0PHP ~8.1.0 || ~8.2.0 || ~8.3.0

1.7.0PHP ~8.2.0 || ~8.3.0 || ~8.4.0

1.8.0PHP ~8.3.0 || ~8.4.0 || ~8.5.0

2.0.0PHP ~8.4.0 || ~8.5.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/c0cb7e57de4834c7e94552864acb7c5640725b5ec0ea8f087ebbf6761dd3c206?d=identicon)[veewee](/maintainers/veewee)

---

Top Contributors

[![veewee](https://avatars.githubusercontent.com/u/1618158?v=4)](https://github.com/veewee "veewee (54 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")[![simoheinonen](https://avatars.githubusercontent.com/u/3840367?v=4)](https://github.com/simoheinonen "simoheinonen (1 commits)")

---

Tags

hacktoberfest

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/php-soap-psr18-transport/health.svg)

```
[![Health](https://phpackages.com/badges/php-soap-psr18-transport/health.svg)](https://phpackages.com/packages/php-soap-psr18-transport)
```

###  Alternatives

[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35789.4k2](/packages/telnyx-telnyx-php)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28150.5k](/packages/phpro-http-tools)[openai-php/client

OpenAI PHP is a supercharged PHP API client that allows you to interact with the Open AI API

5.8k28.0M318](/packages/openai-php-client)[anthropic-ai/sdk

Anthropic PHP SDK

163583.3k17](/packages/anthropic-ai-sdk)[n1ebieski/ksef-php-client

PHP API client that allows you to interact with the API Krajowego Systemu e-Faktur

9067.8k](/packages/n1ebieski-ksef-php-client)[trycourier/courier

Courier PHP SDK

15660.9k](/packages/trycourier-courier)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
