PHPackages                             paxport/soap-react - 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. paxport/soap-react

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

paxport/soap-react
==================

Simple, async SOAP webservice client library, built on top of ReactPHP

1.0.1(6y ago)026.2k↓40.3%MITPHPPHP &gt;=5.3

Since Jul 28Pushed 6y agoCompare

[ Source](https://github.com/LendLord/reactphp-soap)[ Packagist](https://packagist.org/packages/paxport/soap-react)[ Docs](https://github.com/clue/reactphp-soap)[ RSS](/packages/paxport-soap-react/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (5)Used By (0)

clue/reactphp-soap [![Build Status](https://camo.githubusercontent.com/cb91d4877fedaf88aec23cea046a6bce9cfbec79a82f56554c4cea6647cdc045/68747470733a2f2f7472617669732d63692e6f72672f636c75652f72656163747068702d736f61702e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/clue/reactphp-soap)
========================================================================================================================================================================================================================================================================================================

[](#cluereactphp-soap-)

Simple, async [SOAP](https://en.wikipedia.org/wiki/SOAP) web service client library, built on top of [ReactPHP](https://reactphp.org/).

Most notably, SOAP is often used for invoking [Remote procedure calls](https://en.wikipedia.org/wiki/Remote_procedure_call) (RPCs) in distributed systems. Internally, SOAP messages are encoded as XML and usually sent via HTTP POST requests. For the most part, SOAP (originally *Simple Object Access protocol*) is a protocol of the past, and in fact anything but *simple*. It is still in use by many (often *legacy*) systems. This project provides a *simple* API for invoking *async* RPCs to remote web services.

- **Async execution of functions** - Send any number of functions (RPCs) to the remote web service in parallel and process their responses as soon as results come in. The Promise-based design provides a *sane* interface to working with out of bound responses.
- **Async processing of the WSDL** - The WSDL (web service description language) file will be downloaded and processed in the background.
- **Event-driven core** - Internally, everything uses event handlers to react to incoming events, such as an incoming RPC result.
- **Lightweight, SOLID design** - Provides a thin abstraction that is [*just good enough*](https://en.wikipedia.org/wiki/Principle_of_good_enough)and does not get in your way. Built on top of tested components instead of re-inventing the wheel.
- **Good test coverage** - Comes with an automated tests suite and is regularly tested against actual web services in the wild.

**Table of contents**

- [Quickstart example](#quickstart-example)
- [Usage](#usage)
    - [Client](#client)
        - [soapCall()](#soapcall)
        - [getFunctions()](#getfunctions)
        - [getTypes()](#gettypes)
        - [getLocation()](#getlocation)
        - [withLocation()](#withlocation)
    - [Proxy](#proxy)
        - [Functions](#functions)
        - [Promises](#promises)
        - [Cancellation](#cancellation)
        - [Timeouts](#timeouts)
- [Install](#install)
- [Tests](#tests)
- [License](#license)

Quickstart example
------------------

[](#quickstart-example)

Once [installed](#install), you can use the following code to query an example web service via SOAP:

```
$loop = React\EventLoop\Factory::create();
$browser = new Browser($loop);
$wsdl = 'http://example.com/demo.wsdl';

$browser->get($wsdl)->then(function (ResponseInterface $response) use ($browser) {
    $client = new Client($browser, (string)$response->getBody());
    $api = new Proxy($client);

    $api->getBank(array('blz' => '12070000'))->then(function ($result) {
        var_dump('Result', $result);
    });
});

$loop->run();
```

See also the [examples](examples).

Usage
-----

[](#usage)

### Client

[](#client)

The `Client` class is responsible for communication with the remote SOAP WebService server.

It requires a [`Browser`](https://github.com/clue/reactphp-buzz#browser) object bound to the main [`EventLoop`](https://github.com/reactphp/event-loop#usage)in order to handle async requests, the WSDL file contents and an optional array of SOAP options:

```
$loop = React\EventLoop\Factory::create();
$browser = new Clue\React\Buzz\Browser($loop);

$wsdl = ' Note that if you have `ext-xdebug` loaded, this may halt with a fatal error instead of throwing a `SoapFault`. It is not recommended to use this extension in production, so this should only ever affect test environments.

The `Client` constructor accepts an array of options. All given options will be passed through to the underlying `SoapClient`. However, not all options make sense in this async implementation and as such may not have the desired effect. See also [`SoapClient`](http://php.net/manual/en/soapclient.soapclient.php)documentation for more details.

If working in WSDL mode, the `$options` parameter is optional. If working in non-WSDL mode, the WSDL parameter must be set to `null` and the options parameter must contain the `location` and `uri` options, where `location` is the URL of the SOAP server to send the request to, and `uri` is the target namespace of the SOAP service:

```
$client = new Client($browser, null, array(
    'location' => 'http://example.com',
    'uri' => 'http://ping.example.com',
));
```

Similarly, if working in WSDL mode, the `location` option can be used to explicitly overwrite the URL of the SOAP server to send the request to:

```
$client = new Client($browser, $wsdl, array(
    'location' => 'http://example.com'
));
```

You can use the `soap_version` option to change from the default SOAP 1.1 to use SOAP 1.2 instead:

```
$client = new Client($browser, $wsdl, array(
    'soap_version' => SOAP_1_2
));
```

You can use the `classmap` option to map certain WSDL types to PHP classes like this:

```
$client = new Client($browser, $wsdl, array(
    'classmap' => array(
        'getBankResponseType' => BankResponse::class
    )
));
```

The `proxy_host` option (and family) is not supported by this library. As an alternative, you can configure the given `$browser` instance to use an [HTTP proxy server](https://github.com/clue/reactphp-buzz#http-proxy). If you find any other option is missing or not supported here, PRs are much appreciated!

All public methods of the `Client` are considered *advanced usage*. If you want to call RPC functions, see below for the [`Proxy`](#proxy) class.

#### soapCall()

[](#soapcall)

The `soapCall(string $method, mixed[] $arguments): PromiseInterface` method can be used to queue the given function to be sent via SOAP and wait for a response from the remote web service.

```
// advanced usage, see Proxy for recommended alternative
$promise = $client->soapCall('ping', array('hello', 42));
```

Note: This is considered *advanced usage*, you may want to look into using the [`Proxy`](#proxy) instead.

```
$proxy = new Proxy($client);
$promise = $proxy->ping('hello', 42);
```

#### getFunctions()

[](#getfunctions)

The `getFunctions(): string[]|null` method can be used to return an array of functions defined in the WSDL.

It returns the equivalent of PHP's [`SoapClient::__getFunctions()`](http://php.net/manual/en/soapclient.getfunctions.php). In non-WSDL mode, this method returns `null`.

#### getTypes()

[](#gettypes)

The `getTypes(): string[]|null` method can be used to return an array of types defined in the WSDL.

It returns the equivalent of PHP's [`SoapClient::__getTypes()`](http://php.net/manual/en/soapclient.gettypes.php). In non-WSDL mode, this method returns `null`.

#### getLocation()

[](#getlocation)

The `getLocation(string|int $function): string` method can be used to return the location (URI) of the given webservice `$function`.

Note that this is not to be confused with the WSDL file location. A WSDL file can contain any number of function definitions. It's very common that all of these functions use the same location definition. However, technically each function can potentially use a different location.

The `$function` parameter should be a string with the the SOAP function name. See also [`getFunctions()`](#getfunctions) for a list of all available functions.

```
assert('http://example.com/soap/service' === $client->getLocation('echo'));
```

For easier access, this function also accepts a numeric function index. It then uses [`getFunctions()`](#getfunctions) internally to get the function name for the given index. This is particularly useful for the very common case where all functions use the same location and accessing the first location is sufficient.

```
assert('http://example.com/soap/service' === $client->getLocation(0));
```

When the `location` option has been set in the `Client` constructor (such as when in non-WSDL mode) or via the `withLocation()` method, this method returns the value of the given location.

Passing a `$function` not defined in the WSDL file will throw a `SoapFault`.

#### withLocation()

[](#withlocation)

The `withLocation(string $location): self` method can be used to return a new `Client` with the updated location (URI) for all functions.

Note that this is not to be confused with the WSDL file location. A WSDL file can contain any number of function definitions. It's very common that all of these functions use the same location definition. However, technically each function can potentially use a different location.

```
$client = $client->withLocation('http://example.com/soap');

assert('http://example.com/soap' === $client->getLocation('echo'));
```

As an alternative to this method, you can also set the `location` option in the `Client` constructor (such as when in non-WSDL mode).

### Proxy

[](#proxy)

The `Proxy` class wraps an existing [`Client`](#client) instance in order to ease calling SOAP functions.

```
$proxy = new Proxy($client);
```

> Note that this class is called "Proxy" because it will forward (proxy) all method calls to the actual SOAP service via the underlying [`Client::soapCall()`](#soapcall) method. This is not to be confused with using a proxy server. See [`Client`](#client) documentation for more details on how to use an HTTP proxy server.

#### Functions

[](#functions)

Each and every method call to the `Proxy` class will be sent via SOAP.

```
$proxy->myMethod($myArg1, $myArg2)->then(function ($response) {
    // result received
});
```

Please refer to your WSDL or its accompanying documentation for details on which functions and arguments are supported.

#### Promises

[](#promises)

Issuing SOAP functions is async (non-blocking), so you can actually send multiple RPC requests in parallel. The web service will respond to each request with a return value. The order is not guaranteed. Sending requests uses a [Promise](https://github.com/reactphp/promise)-based interface that makes it easy to react to when a request is *fulfilled*(i.e. either successfully resolved or rejected with an error):

```
$proxy->demo()->then(
    function ($response) {
        // response received for demo function
    },
    function (Exception $e) {
        // an error occured while executing the request
    }
});
```

#### Cancellation

[](#cancellation)

The returned Promise is implemented in such a way that it can be cancelled when it is still pending. Cancelling a pending promise will reject its value with an Exception and clean up any underlying resources.

```
$promise = $proxy->demo();

$loop->addTimer(2.0, function () use ($promise) {
    $promise->cancel();
});
```

#### Timeouts

[](#timeouts)

This library uses a very efficient HTTP implementation, so most SOAP requests should usually be completed in mere milliseconds. However, when sending SOAP requests over an unreliable network (the internet), there are a number of things that can go wrong and may cause the request to fail after a time. As such, timeouts are handled by the underlying HTTP library and this library respects PHP's `default_socket_timeout` setting (default 60s) as a timeout for sending the outgoing SOAP request and waiting for a successful response and will otherwise cancel the pending request and reject its value with an Exception.

Note that this timeout value covers creating the underlying transport connection, sending the SOAP request, waiting for the remote service to process the request and receiving the full SOAP response. To pass a custom timeout value, you can assign the underlying [`timeout` option](https://github.com/clue/reactphp-buzz#timeouts)like this:

```
$browser = new Browser($loop);
$browser = $browser->withOptions(array(
    'timeout' => 10.0
));

$client = new Client($browser, $wsdl);
$proxy = new Proxy($client);

$proxy->demo()->then(function ($response) {
    // response received within 10 seconds maximum
    var_dump($response);
});
```

Similarly, you can use a negative timeout value to not apply a timeout at all or use a `null` value to restore the default handling. Note that the underlying connection may still impose a different timeout value. See also the underlying [`timeout` option](https://github.com/clue/reactphp-buzz#timeouts) for more details.

Install
-------

[](#install)

The recommended way to install this library is [through Composer](https://getcomposer.org). [New to Composer?](https://getcomposer.org/doc/00-intro.md)

This project follows [SemVer](https://semver.org/). This will install the latest supported version:

```
$ composer require clue/soap-react:^1.0
```

See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

This project aims to run on any platform and thus only requires `ext-soap` and supports running on legacy PHP 5.3 through current PHP 7+ and HHVM. It's *highly recommended to use PHP 7+* for this project.

Tests
-----

[](#tests)

To run the test suite, you first need to clone this repo and then install all dependencies [through Composer](https://getcomposer.org):

```
$ composer install
```

To run the test suite, go to the project root and run:

```
$ php vendor/bin/phpunit
```

The test suite also contains a number of functional integration tests that rely on a stable internet connection. If you do not want to run these, they can simply be skipped like this:

```
$ php vendor/bin/phpunit --exclude-group internet
```

License
-------

[](#license)

This project is released under the permissive [MIT license](LICENSE).

> Did you know that I offer custom development services and issuing invoices for sponsorships of releases and for contributions? Contact me (@clue) for details.

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity26

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 96.1% 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 ~655 days

Total

4

Last Release

2345d ago

Major Versions

v0.2.0 → v1.0.02018-11-07

### Community

Maintainers

![](https://www.gravatar.com/avatar/fdba952a95dda2ec80c8aa26918301779a21bff934fcec98bc61767508a0e11e?d=identicon)[Semenov Dmitriy](/maintainers/Semenov%20Dmitriy)

---

Top Contributors

[![clue](https://avatars.githubusercontent.com/u/776829?v=4)](https://github.com/clue "clue (73 commits)")[![andreybolonin](https://avatars.githubusercontent.com/u/2576509?v=4)](https://github.com/andreybolonin "andreybolonin (1 commits)")[![carusogabriel](https://avatars.githubusercontent.com/u/16328050?v=4)](https://github.com/carusogabriel "carusogabriel (1 commits)")[![WyriHaximus](https://avatars.githubusercontent.com/u/147145?v=4)](https://github.com/WyriHaximus "WyriHaximus (1 commits)")

---

Tags

reactphpsoapwebservicewsdlsoapclient

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/paxport-soap-react/health.svg)

```
[![Health](https://phpackages.com/badges/paxport-soap-react/health.svg)](https://phpackages.com/packages/paxport-soap-react)
```

###  Alternatives

[clue/soap-react

Simple, async SOAP webservice client library, built on top of ReactPHP

64118.0k2](/packages/clue-soap-react)[react/http

Event-driven, streaming HTTP client and server implementation for ReactPHP

78026.4M414](/packages/react-http)[amabnl/amadeus-ws-client

SOAP Web Service client library for interacting with the Amadeus GDS through its SOAP interface

204248.5k](/packages/amabnl-amadeus-ws-client)[clue/http-proxy-react

Async HTTP proxy connector, tunnel any TCP/IP-based protocol through an HTTP CONNECT proxy server, built on top of ReactPHP

472.3M33](/packages/clue-http-proxy-react)[camcima/camcima-soap-client

Wrapper around PHP SoapClient class

2672.0k2](/packages/camcima-camcima-soap-client)[clue/docker-react

Async, event-driven access to the Docker Engine API, built on top of ReactPHP.

113154.9k1](/packages/clue-docker-react)

PHPackages © 2026

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