Skip to content

Simplify usage by updating to new default loop and making Browser optional #56

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 21 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ Once [installed](#install), you can use the following code to query an example
web service via SOAP:

```php
$loop = React\EventLoop\Factory::create();
$browser = new React\Http\Browser($loop);
<?php

require __DIR__ . '/vendor/autoload.php';

$browser = new React\Http\Browser();
$wsdl = 'http://example.com/demo.wsdl';

$browser->get($wsdl)->then(function (Psr\Http\Message\ResponseInterface $response) use ($browser) {
Expand All @@ -79,8 +82,6 @@ $browser->get($wsdl)->then(function (Psr\Http\Message\ResponseInterface $respons
var_dump('Result', $result);
});
});

$loop->run();
```

See also the [examples](examples).
Expand All @@ -90,30 +91,26 @@ See also the [examples](examples).
### Client

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

It requires a [`Browser`](https://github.com/reactphp/http#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
WebService server. It requires the WSDL file contents and an optional
array of SOAP options:

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

$wsdl = '<?xml …';
$options = array();

$client = new Clue\React\Soap\Client($browser, $wsdl, $options);
$client = new Clue\React\Soap\Client(null, $wsdl, $options);
```

This class takes an optional `Browser|null $browser` parameter that can be used to
pass the browser instance to use for this object.
If you need custom connector settings (DNS resolution, TLS parameters, timeouts,
proxy servers etc.), you can explicitly pass a custom instance of the
[`ConnectorInterface`](https://github.com/reactphp/socket#connectorinterface)
to the [`Browser`](https://github.com/reactphp/http#browser) instance:
to the [`Browser`](https://github.com/reactphp/http#browser) instance
and pass it as an additional argument to the `Client` like this:

```php
$connector = new React\Socket\Connector($loop, array(
$connector = new React\Socket\Connector(array(
'dns' => '127.0.0.1',
'tcp' => array(
'bindto' => '192.168.10.1:0'
Expand All @@ -124,7 +121,7 @@ $connector = new React\Socket\Connector($loop, array(
)
));

$browser = new React\Http\Browser($loop, $connector);
$browser = new React\Http\Browser($connector);
$client = new Clue\React\Soap\Client($browser, $wsdl);
```

Expand All @@ -134,7 +131,7 @@ you to use local WSDL files, WSDL files from a cache or the most common form,
downloading the WSDL file contents from an URL through the `Browser`:

```php
$browser = new React\Http\Browser($loop);
$browser = new React\Http\Browser();

$browser->get($url)->then(
function (Psr\Http\Message\ResponseInterface $response) use ($browser) {
Expand All @@ -155,7 +152,7 @@ parsed, this will throw a `SoapFault`:

```php
try {
$client = new Clue\React\Soap\Client($browser, $wsdl);
$client = new Clue\React\Soap\Client(null, $wsdl);
} catch (SoapFault $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
}
Expand All @@ -179,7 +176,7 @@ the URL of the SOAP server to send the request to, and `uri` is the target
namespace of the SOAP service:

```php
$client = new Clue\React\Soap\Client($browser, null, array(
$client = new Clue\React\Soap\Client(null, null, array(
'location' => 'http://example.com',
'uri' => 'http://ping.example.com',
));
Expand All @@ -189,7 +186,7 @@ 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:

```php
$client = new Clue\React\Soap\Client($browser, $wsdl, array(
$client = new Clue\React\Soap\Client(null, $wsdl, array(
'location' => 'http://example.com'
));
```
Expand All @@ -198,7 +195,7 @@ You can use the `soap_version` option to change from the default SOAP 1.1 to
use SOAP 1.2 instead:

```php
$client = new Clue\React\Soap\Client($browser, $wsdl, array(
$client = new Clue\React\Soap\Client(null, $wsdl, array(
'soap_version' => SOAP_1_2
));
```
Expand All @@ -207,7 +204,7 @@ You can use the `classmap` option to map certain WSDL types to PHP classes
like this:

```php
$client = new Clue\React\Soap\Client($browser, $wsdl, array(
$client = new Clue\React\Soap\Client(null, $wsdl, array(
'classmap' => array(
'getBankResponseType' => BankResponse::class
)
Expand Down Expand Up @@ -366,7 +363,7 @@ clean up any underlying resources.
```php
$promise = $proxy->demo();

$loop->addTimer(2.0, function () use ($promise) {
Loop::addTimer(2.0, function () use ($promise) {
$promise->cancel();
});
```
Expand All @@ -389,7 +386,7 @@ pass the timeout to the [underlying `Browser`](https://github.com/reactphp/http#
like this:

```php
$browser = new React\Http\Browser($loop);
$browser = new React\Http\Browser();
$browser = $browser->withTimeout(10.0);

$client = new Clue\React\Soap\Client($browser, $wsdl);
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"require": {
"php": ">=7.1",
"react/http": "^1.0",
"react/http": "^1.5",
"react/promise": "^2.1 || ^1.2",
"ext-soap": "*"
},
Expand Down
5 changes: 1 addition & 4 deletions examples/01-client-blz-wsdl.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$browser = new React\Http\Browser($loop);
$browser = new React\Http\Browser();

$blz = isset($argv[1]) ? $argv[1] : '12070000';

Expand All @@ -21,5 +20,3 @@ function (Exception $e) {
}
);
});

$loop->run();
7 changes: 1 addition & 6 deletions examples/02-client-blz-non-wsdl.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$browser = new React\Http\Browser($loop);

$blz = isset($argv[1]) ? $argv[1] : '12070000';

$client = new Clue\React\Soap\Client($browser, null, array(
$client = new Clue\React\Soap\Client(null, null, array(
'location' => 'http://www.thomas-bayer.com/axis2/services/BLZService',
'uri' => 'http://thomas-bayer.com/blz/',
'use' => SOAP_LITERAL
Expand All @@ -23,5 +20,3 @@ function (Exception $e) {
echo 'ERROR: ' . $e->getMessage() . PHP_EOL;
}
);

$loop->run();
5 changes: 1 addition & 4 deletions examples/11-wsdl-info.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$browser = new React\Http\Browser($loop);
$browser = new React\Http\Browser();

$wsdl = isset($argv[1]) ? $argv[1] : 'http://www.thomas-bayer.com/axis2/services/BLZService?wsdl';

Expand All @@ -21,5 +20,3 @@ function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
}
);

$loop->run();
49 changes: 24 additions & 25 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,26 @@

/**
* The `Client` class is responsible for communication with the remote SOAP
* WebService server.
*
* It requires a [`Browser`](https://github.com/reactphp/http#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
* WebService server. It requires the WSDL file contents and an optional
* array of SOAP options:
*
* ```php
* $loop = React\EventLoop\Factory::create();
* $browser = new React\Http\Browser($loop);
*
* $wsdl = '<?xml …';
* $options = array();
*
* $client = new Clue\React\Soap\Client($browser, $wsdl, $options);
* $client = new Clue\React\Soap\Client(null, $wsdl, $options);
* ```
*
* This class takes an optional `Browser|null $browser` parameter that can be used to
* pass the browser instance to use for this object.
* If you need custom connector settings (DNS resolution, TLS parameters, timeouts,
* proxy servers etc.), you can explicitly pass a custom instance of the
* [`ConnectorInterface`](https://github.com/reactphp/socket#connectorinterface)
* to the [`Browser`](https://github.com/clue/reactphp/http#browser) instance:
* to the [`Browser`](https://github.com/reactphp/http#browser) instance
* and pass it as an additional argument to the `Client` like this:
*
* ```php
* $connector = new React\Socket\Connector($loop, array(
* $connector = new React\Socket\Connector(array(
* 'dns' => '127.0.0.1',
* 'tcp' => array(
* 'bindto' => '192.168.10.1:0'
Expand All @@ -45,7 +41,7 @@
* )
* ));
*
* $browser = new React\Http\Browser($loop, $connector);
* $browser = new React\Http\Browser($connector);
* $client = new Clue\React\Soap\Client($browser, $wsdl);
* ```
*
Expand All @@ -55,7 +51,7 @@
* downloading the WSDL file contents from an URL through the `Browser`:
*
* ```php
* $browser = new React\Http\Browser($loop);
* $browser = new React\Http\Browser();
*
* $browser->get($url)->then(
* function (Psr\Http\Message\ResponseInterface $response) use ($browser) {
Expand All @@ -76,7 +72,7 @@
*
* ```php
* try {
* $client = new Clue\React\Soap\Client($browser, $wsdl);
* $client = new Clue\React\Soap\Client(null, $wsdl);
* } catch (SoapFault $e) {
* echo 'Error: ' . $e->getMessage() . PHP_EOL;
* }
Expand All @@ -100,7 +96,7 @@
* namespace of the SOAP service:
*
* ```php
* $client = new Clue\React\Soap\Client($browser, null, array(
* $client = new Clue\React\Soap\Client(null, null, array(
* 'location' => 'http://example.com',
* 'uri' => 'http://ping.example.com',
* ));
Expand All @@ -110,7 +106,7 @@
* explicitly overwrite the URL of the SOAP server to send the request to:
*
* ```php
* $client = new Clue\React\Soap\Client($browser, $wsdl, array(
* $client = new Clue\React\Soap\Client(null, $wsdl, array(
* 'location' => 'http://example.com'
* ));
* ```
Expand All @@ -119,7 +115,7 @@
* use SOAP 1.2 instead:
*
* ```php
* $client = new Clue\React\Soap\Client($browser, $wsdl, array(
* $client = new Clue\React\Soap\Client(null, $wsdl, array(
* 'soap_version' => SOAP_1_2
* ));
* ```
Expand All @@ -128,7 +124,7 @@
* like this:
*
* ```php
* $client = new Clue\React\Soap\Client($browser, $wsdl, array(
* $client = new Clue\React\Soap\Client(null, $wsdl, array(
* 'classmap' => array(
* 'getBankResponseType' => BankResponse::class
* )
Expand All @@ -146,29 +142,32 @@
*/
class Client
{
/** @var Browser */
private $browser;

private $encoder;
private $decoder;

/**
* Instantiate a new SOAP client for the given WSDL contents.
*
* @param Browser $browser
* @param string|null $wsdlContents
* @param array $options
* @param ?Browser $browser
* @param ?string $wsdlContents
* @param ?array $options
*/
public function __construct(Browser $browser, ?string $wsdlContents, array $options = array())
public function __construct(?Browser $browser, ?string $wsdlContents, array $options = array())
{
$wsdl = $wsdlContents !== null ? 'data://text/plain;base64,' . base64_encode($wsdlContents) : null;

$this->browser = $browser ?? new Browser();

// Accept HTTP responses with error status codes as valid responses.
// This is done in order to process these error responses through the normal SOAP decoder.
// Additionally, we explicitly limit number of redirects to zero because following redirects makes little sense
// because it transforms the POST request to a GET one and hence loses the SOAP request body.
$browser = $browser->withRejectErrorResponse(false);
$browser = $browser->withFollowRedirects(0);
$this->browser = $this->browser->withRejectErrorResponse(false);
$this->browser = $this->browser->withFollowRedirects(0);

$this->browser = $browser;
$this->encoder = new ClientEncoder($wsdl, $options);
$this->decoder = new ClientDecoder($wsdl, $options);
}
Expand Down
Loading