Skip to content

Commit c85158a

Browse files
authored
Merge pull request #264 from clue-labs/connector-signature
Update `Connector` signature to take `$context` as first argument
2 parents 22d3b31 + 1941c6c commit c85158a

File tree

5 files changed

+254
-97
lines changed

5 files changed

+254
-97
lines changed

README.md

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -948,12 +948,6 @@ also shares all of their features and implementation details.
948948
If you want to typehint in your higher-level protocol implementation, you SHOULD
949949
use the generic [`ConnectorInterface`](#connectorinterface) instead.
950950

951-
This class takes an optional `LoopInterface|null $loop` parameter that can be used to
952-
pass the event loop instance to use for this object. You can use a `null` value
953-
here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
954-
This value SHOULD NOT be given unless you're sure you want to explicitly use a
955-
given event loop instance.
956-
957951
As of `v1.4.0`, the `Connector` class defaults to using the
958952
[happy eyeballs algorithm](https://en.wikipedia.org/wiki/Happy_Eyeballs) to
959953
automatically connect over IPv4 or IPv6 when a hostname is given.
@@ -964,7 +958,7 @@ If you want to revert to the old behavior of only doing an IPv4 lookup and
964958
only attempt a single IPv4 connection, you can set up the `Connector` like this:
965959

966960
```php
967-
$connector = new React\Socket\Connector(null, array(
961+
$connector = new React\Socket\Connector(array(
968962
'happy_eyeballs' => false
969963
));
970964
```
@@ -978,7 +972,7 @@ If you explicitly want to use a custom DNS server (such as a local DNS relay or
978972
a company wide DNS server), you can set up the `Connector` like this:
979973

980974
```php
981-
$connector = new React\Socket\Connector(null, array(
975+
$connector = new React\Socket\Connector(array(
982976
'dns' => '127.0.1.1'
983977
));
984978

@@ -992,7 +986,7 @@ If you do not want to use a DNS resolver at all and want to connect to IP
992986
addresses only, you can also set up your `Connector` like this:
993987

994988
```php
995-
$connector = new React\Socket\Connector(null, array(
989+
$connector = new React\Socket\Connector(array(
996990
'dns' => false
997991
));
998992

@@ -1009,7 +1003,7 @@ can also set up your `Connector` like this:
10091003
$dnsResolverFactory = new React\Dns\Resolver\Factory();
10101004
$resolver = $dnsResolverFactory->createCached('127.0.1.1');
10111005

1012-
$connector = new React\Socket\Connector(null, array(
1006+
$connector = new React\Socket\Connector(array(
10131007
'dns' => $resolver
10141008
));
10151009

@@ -1024,7 +1018,7 @@ respects your `default_socket_timeout` ini setting (which defaults to 60s).
10241018
If you want a custom timeout value, you can simply pass this like this:
10251019

10261020
```php
1027-
$connector = new React\Socket\Connector(null, array(
1021+
$connector = new React\Socket\Connector(array(
10281022
'timeout' => 10.0
10291023
));
10301024
```
@@ -1033,7 +1027,7 @@ Similarly, if you do not want to apply a timeout at all and let the operating
10331027
system handle this, you can pass a boolean flag like this:
10341028

10351029
```php
1036-
$connector = new React\Socket\Connector(null, array(
1030+
$connector = new React\Socket\Connector(array(
10371031
'timeout' => false
10381032
));
10391033
```
@@ -1044,7 +1038,7 @@ pass boolean flags like this:
10441038

10451039
```php
10461040
// only allow secure TLS connections
1047-
$connector = new React\Socket\Connector(null, array(
1041+
$connector = new React\Socket\Connector(array(
10481042
'tcp' => false,
10491043
'tls' => true,
10501044
'unix' => false,
@@ -1063,7 +1057,7 @@ pass arrays of context options like this:
10631057

10641058
```php
10651059
// allow insecure TLS connections
1066-
$connector = new React\Socket\Connector(null, array(
1060+
$connector = new React\Socket\Connector(array(
10671061
'tcp' => array(
10681062
'bindto' => '192.168.0.1:0'
10691063
),
@@ -1084,7 +1078,7 @@ SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
10841078
want to negotiate with the remote side:
10851079

10861080
```php
1087-
$connector = new React\Socket\Connector(null, array(
1081+
$connector = new React\Socket\Connector(array(
10881082
'tls' => array(
10891083
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
10901084
)
@@ -1110,7 +1104,7 @@ $tls = new React\Socket\SecureConnector($tcp);
11101104

11111105
$unix = new React\Socket\UnixConnector();
11121106

1113-
$connector = new React\Socket\Connector(null, array(
1107+
$connector = new React\Socket\Connector(array(
11141108
'tcp' => $tcp,
11151109
'tls' => $tls,
11161110
'unix' => $unix,
@@ -1137,6 +1131,24 @@ $connector->connect('google.com:80')->then(function (React\Socket\ConnectionInte
11371131
Internally, the `tcp://` and `tls://` connectors will always be wrapped by
11381132
`TimeoutConnector`, unless you disable timeouts like in the above example.
11391133

1134+
This class takes an optional `LoopInterface|null $loop` parameter that can be used to
1135+
pass the event loop instance to use for this object. You can use a `null` value
1136+
here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
1137+
This value SHOULD NOT be given unless you're sure you want to explicitly use a
1138+
given event loop instance.
1139+
1140+
> Changelog v1.9.0: The constructur signature has been updated to take the
1141+
> optional `$context` as the first parameter and the optional `$loop` as a second
1142+
> argument. The previous signature has been deprecated and should not be used anymore.
1143+
>
1144+
> ```php
1145+
> // constructor signature as of v1.9.0
1146+
> $connector = new React\Socket\Connector(array $context = [], ?LoopInterface $loop = null);
1147+
>
1148+
> // legacy constructor signature before v1.9.0
1149+
> $connector = new React\Socket\Connector(?LoopInterface $loop = null, array $context = []);
1150+
> ```
1151+
11401152
### Advanced client usage
11411153
11421154
#### TcpConnector

src/Connector.php

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use React\Dns\Config\Config as DnsConfig;
66
use React\Dns\Resolver\Factory as DnsFactory;
77
use React\Dns\Resolver\ResolverInterface;
8-
use React\EventLoop\Loop;
98
use React\EventLoop\LoopInterface;
109

1110
/**
@@ -16,7 +15,7 @@
1615
* as plaintext TCP/IP, secure TLS or local Unix connection streams.
1716
*
1817
* Under the hood, the `Connector` is implemented as a *higher-level facade*
19-
* or the lower-level connectors implemented in this package. This means it
18+
* for the lower-level connectors implemented in this package. This means it
2019
* also shares all of their features and implementation details.
2120
* If you want to typehint in your higher-level protocol implementation, you SHOULD
2221
* use the generic [`ConnectorInterface`](#connectorinterface) instead.
@@ -27,11 +26,48 @@ final class Connector implements ConnectorInterface
2726
{
2827
private $connectors = array();
2928

30-
public function __construct(LoopInterface $loop = null, array $options = array())
29+
/**
30+
* Instantiate new `Connector`
31+
*
32+
* ```php
33+
* $connector = new React\Socket\Connector();
34+
* ```
35+
*
36+
* This class takes two optional arguments for more advanced usage:
37+
*
38+
* ```php
39+
* // constructor signature as of v1.9.0
40+
* $connector = new React\Socket\Connector(array $context = [], ?LoopInterface $loop = null);
41+
*
42+
* // legacy constructor signature before v1.9.0
43+
* $connector = new React\Socket\Connector(?LoopInterface $loop = null, array $context = []);
44+
* ```
45+
*
46+
* This class takes an optional `LoopInterface|null $loop` parameter that can be used to
47+
* pass the event loop instance to use for this object. You can use a `null` value
48+
* here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
49+
* This value SHOULD NOT be given unless you're sure you want to explicitly use a
50+
* given event loop instance.
51+
*
52+
* @param array|LoopInterface|null $context
53+
* @param null|LoopInterface|array $loop
54+
* @throws \InvalidArgumentException for invalid arguments
55+
*/
56+
public function __construct($context = array(), $loop = null)
3157
{
32-
$loop = $loop ?: Loop::get();
58+
// swap arguments for legacy constructor signature
59+
if (($context instanceof LoopInterface || $context === null) && (\func_num_args() <= 1 || \is_array($loop))) {
60+
$swap = $loop === null ? array(): $loop;
61+
$loop = $context;
62+
$context = $swap;
63+
}
64+
65+
if (!\is_array($context) || ($loop !== null && !$loop instanceof LoopInterface)) {
66+
throw new \InvalidArgumentException('Expected "array $context" and "?LoopInterface $loop" arguments');
67+
}
68+
3369
// apply default options if not explicitly given
34-
$options += array(
70+
$context += array(
3571
'tcp' => true,
3672
'tls' => true,
3773
'unix' => true,
@@ -41,25 +77,25 @@ public function __construct(LoopInterface $loop = null, array $options = array()
4177
'happy_eyeballs' => true,
4278
);
4379

44-
if ($options['timeout'] === true) {
45-
$options['timeout'] = (float)\ini_get("default_socket_timeout");
80+
if ($context['timeout'] === true) {
81+
$context['timeout'] = (float)\ini_get("default_socket_timeout");
4682
}
4783

48-
if ($options['tcp'] instanceof ConnectorInterface) {
49-
$tcp = $options['tcp'];
84+
if ($context['tcp'] instanceof ConnectorInterface) {
85+
$tcp = $context['tcp'];
5086
} else {
5187
$tcp = new TcpConnector(
5288
$loop,
53-
\is_array($options['tcp']) ? $options['tcp'] : array()
89+
\is_array($context['tcp']) ? $context['tcp'] : array()
5490
);
5591
}
5692

57-
if ($options['dns'] !== false) {
58-
if ($options['dns'] instanceof ResolverInterface) {
59-
$resolver = $options['dns'];
93+
if ($context['dns'] !== false) {
94+
if ($context['dns'] instanceof ResolverInterface) {
95+
$resolver = $context['dns'];
6096
} else {
61-
if ($options['dns'] !== true) {
62-
$config = $options['dns'];
97+
if ($context['dns'] !== true) {
98+
$config = $context['dns'];
6399
} else {
64100
// try to load nameservers from system config or default to Google's public DNS
65101
$config = DnsConfig::loadSystemConfigBlocking();
@@ -75,52 +111,52 @@ public function __construct(LoopInterface $loop = null, array $options = array()
75111
);
76112
}
77113

78-
if ($options['happy_eyeballs'] === true) {
114+
if ($context['happy_eyeballs'] === true) {
79115
$tcp = new HappyEyeBallsConnector($loop, $tcp, $resolver);
80116
} else {
81117
$tcp = new DnsConnector($tcp, $resolver);
82118
}
83119
}
84120

85-
if ($options['tcp'] !== false) {
86-
$options['tcp'] = $tcp;
121+
if ($context['tcp'] !== false) {
122+
$context['tcp'] = $tcp;
87123

88-
if ($options['timeout'] !== false) {
89-
$options['tcp'] = new TimeoutConnector(
90-
$options['tcp'],
91-
$options['timeout'],
124+
if ($context['timeout'] !== false) {
125+
$context['tcp'] = new TimeoutConnector(
126+
$context['tcp'],
127+
$context['timeout'],
92128
$loop
93129
);
94130
}
95131

96-
$this->connectors['tcp'] = $options['tcp'];
132+
$this->connectors['tcp'] = $context['tcp'];
97133
}
98134

99-
if ($options['tls'] !== false) {
100-
if (!$options['tls'] instanceof ConnectorInterface) {
101-
$options['tls'] = new SecureConnector(
135+
if ($context['tls'] !== false) {
136+
if (!$context['tls'] instanceof ConnectorInterface) {
137+
$context['tls'] = new SecureConnector(
102138
$tcp,
103139
$loop,
104-
\is_array($options['tls']) ? $options['tls'] : array()
140+
\is_array($context['tls']) ? $context['tls'] : array()
105141
);
106142
}
107143

108-
if ($options['timeout'] !== false) {
109-
$options['tls'] = new TimeoutConnector(
110-
$options['tls'],
111-
$options['timeout'],
144+
if ($context['timeout'] !== false) {
145+
$context['tls'] = new TimeoutConnector(
146+
$context['tls'],
147+
$context['timeout'],
112148
$loop
113149
);
114150
}
115151

116-
$this->connectors['tls'] = $options['tls'];
152+
$this->connectors['tls'] = $context['tls'];
117153
}
118154

119-
if ($options['unix'] !== false) {
120-
if (!$options['unix'] instanceof ConnectorInterface) {
121-
$options['unix'] = new UnixConnector($loop);
155+
if ($context['unix'] !== false) {
156+
if (!$context['unix'] instanceof ConnectorInterface) {
157+
$context['unix'] = new UnixConnector($loop);
122158
}
123-
$this->connectors['unix'] = $options['unix'];
159+
$this->connectors['unix'] = $context['unix'];
124160
}
125161
}
126162

@@ -140,4 +176,3 @@ public function connect($uri)
140176
return $this->connectors[$scheme]->connect($uri);
141177
}
142178
}
143-

0 commit comments

Comments
 (0)