Completed
Push — master ( 1c93c9...59f97a )
by Dominik
01:53
created

Uri::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
cc 1
eloc 19
nc 1
nop 9

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Saxulum\HttpMessage;
4
5
use Psr\Http\Message\UriInterface;
6
7
final class Uri implements UriInterface
8
{
9
    /**
10
     * @var string|null
11
     */
12
    private $scheme;
13
14
    /**
15
     * @var string|null
16
     */
17
    private $host;
18
19
    /**
20
     * @var int|null
21
     */
22
    private $port;
23
24
    const PORT_HTTP = 80;
25
    const PORT_HTTPS = 443;
26
27
    /**
28
     * @var string|null
29
     */
30
    private $user;
31
32
    /**
33
     * @var string|null
34
     */
35
    private $password;
36
37
    /**
38
     * @var string|null
39
     */
40
    private $path;
41
42
    /**
43
     * @var string|null
44
     */
45
    private $query;
46
47
    /**
48
     * @var string|null
49
     */
50
    private $fragment;
51
52
    /**
53
     * @var UriInterface|null
54
     */
55
    private $previous;
56
57
    /**
58
     * @param string|null       $scheme
59
     * @param string|null       $host
60
     * @param int|null          $port
61
     * @param string|null       $user
62
     * @param string|null       $password
63
     * @param string|null       $path
64
     * @param string|null       $query
65
     * @param string|null       $fragment
66
     * @param UriInterface|null $previous
67
     */
68
    public function __construct(
69
        string $scheme = null,
70
        string $host = null,
71
        int $port = null,
72
        string $user = null,
73
        string $password = null,
74
        string $path = null,
75
        string $query = null,
76
        string $fragment = null,
77
        UriInterface $previous = null
78
    ) {
79
        $this->scheme = $scheme;
80
        $this->host = $host;
81
        $this->port = $port;
82
        $this->user = $user;
83
        $this->password = $password;
84
        $this->path = $path;
85
        $this->query = $query;
86
        $this->fragment = $fragment;
87
        $this->previous = $previous;
88
    }
89
90
    /**
91
     * @param string            $uri
92
     * @param UriInterface|null $previous
93
     *
94
     * @return UriInterface
95
     *
96
     * @throws \InvalidArgumentException
97
     */
98
    public static function create(string $uri, UriInterface $previous = null)
99
    {
100
        $uriParts = parse_url($uri);
101
        if (false === $uriParts) {
102
            throw new \InvalidArgumentException(sprintf('Invalid uri format for parse_url: %s', $uri));
103
        }
104
105
        return new self(
106
            $uriParts['scheme'] ?? null,
107
            $uriParts['host'] ?? null,
108
            $uriParts['port'] ?? null,
109
            $uriParts['user'] ?? null,
110
            $uriParts['pass'] ?? null,
111
            $uriParts['path'] ?? null,
112
            $uriParts['query'] ?? null,
113
            $uriParts['fragment'] ?? null,
114
            $previous
115
        );
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function getScheme(): string
122
    {
123
        return strtolower((string) $this->scheme);
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function getAuthority(): string
130
    {
131
        if ('' === $host = $this->getHost()) {
132
            return '';
133
        }
134
135
        $authority = '';
136
137
        if ('' !== $userInfo = $this->getUserInfo()) {
138
            $authority .= $userInfo.'@';
139
        }
140
141
        $authority .= $host;
142
143
        if (null !== $port = $this->getPort()) {
144
            $authority .= ':'.$port;
145
        }
146
147
        return $authority;
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function getUserInfo(): string
154
    {
155
        if (null === $this->user) {
156
            return '';
157
        }
158
159
        if (null === $this->password) {
160
            return $this->user;
161
        }
162
163
        return $this->user.':'.$this->password;
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169
    public function getHost(): string
170
    {
171
        return strtolower((string) $this->host);
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function getPort()
178
    {
179
        if (null === $this->port) {
180
            return null;
181
        }
182
183
        if ($this->port === $this->getPortForScheme($this->getScheme())) {
184
            return null;
185
        }
186
187
        return $this->port;
188
    }
189
190
    /**
191
     * {@inheritdoc}
192
     */
193
    public function getPath(): string
194
    {
195
        return (string) $this->path;
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201
    public function getQuery(): string
202
    {
203
        return (string) $this->query;
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209
    public function getFragment(): string
210
    {
211
        return (string) $this->fragment;
212
    }
213
214
    /**
215
     * @return UriInterface|null
216
     */
217
    public function getPrevious()
218
    {
219
        return $this->previous;
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225
    public function withScheme($scheme): self
226
    {
227
        return $this->with(['scheme' => $scheme]);
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     */
233
    public function withUserInfo($user, $password = null): self
234
    {
235
        return $this->with(['user' => $user, 'password' => $password]);
236
    }
237
238
    /**
239
     * {@inheritdoc}
240
     */
241
    public function withHost($host): self
242
    {
243
        return $this->with(['host' => $host]);
244
    }
245
246
    /**
247
     * {@inheritdoc}
248
     */
249
    public function withPort($port): self
250
    {
251
        return $this->with(['port' => $port]);
252
    }
253
254
    /**
255
     * {@inheritdoc}
256
     */
257
    public function withPath($path): self
258
    {
259
        return $this->with(['path' => $path]);
260
    }
261
262
    /**
263
     * {@inheritdoc}
264
     */
265
    public function withQuery($query): self
266
    {
267
        return $this->with(['query' => $query]);
268
    }
269
270
    /**
271
     * {@inheritdoc}
272
     */
273
    public function withFragment($fragment): self
274
    {
275
        return $this->with(['fragment' => $fragment]);
276
    }
277
278
    /**
279
     * {@inheritdoc}
280
     */
281
    public function __toString(): string
282
    {
283
        $uri = '';
284
285
        if ('' !== $scheme = $this->getScheme()) {
286
            $uri .= $scheme.':';
287
        }
288
289
        if ('' !== $authority = $this->getAuthority()) {
290
            $uri .= '//'.$authority;
291
        }
292
293
        if ('' !== $path = $this->getPath()) {
294
            $uri .= $this->getPathForUri($authority, $path);
295
        }
296
297
        if ('' !== $query = $this->getQuery()) {
298
            $uri .= '?'.$query;
299
        }
300
301
        if ('' !== $fragment = $this->getFragment()) {
302
            $uri .= '#'.$fragment;
303
        }
304
305
        return $uri;
306
    }
307
308
    /**
309
     * @param string $scheme
310
     *
311
     * @return int|null
312
     */
313
    private function getPortForScheme(string $scheme)
314
    {
315
        $constantName = 'PORT_'.strtoupper($scheme);
316
        $reflection = new \ReflectionObject($this);
317
        if ($reflection->hasConstant($constantName)) {
318
            return $reflection->getConstant($constantName);
319
        }
320
321
        return null;
322
    }
323
324
    /**
325
     * @param string $authority
326
     * @param string $path
327
     *
328
     * @return string
329
     */
330
    private function getPathForUri(string $authority, string $path): string
331
    {
332
        if ('' !== $authority) {
333
            return $this->getPathForUriWithAuthority($path);
334
        }
335
336
        return $this->getPathForUriWithoutAuthority($path);
337
    }
338
339
    /**
340
     * @param string $path
341
     *
342
     * @return string
343
     */
344
    private function getPathForUriWithAuthority(string $path)
345
    {
346
        return '/' === $path[0] ? $path : '/'.$path;
347
    }
348
349
    /**
350
     * @param string $path
351
     *
352
     * @return string
353
     */
354
    private function getPathForUriWithoutAuthority(string $path)
355
    {
356
        $pathLength = strlen($path);
357
        for ($i = 0; $i < $pathLength; ++$i) {
358
            if ('/' !== $path[$i]) {
359
                break;
360
            }
361
        }
362
363
        return 0 === $i ? $path : '/'.substr($path, $i);
364
    }
365
366
    /**
367
     * @param array $arguments
368
     *
369
     * @return Uri
370
     */
371
    public function with(array $arguments): self
372
    {
373
        $defaultArguments = [
374
            'scheme' => $this->scheme,
375
            'host' => $this->host,
376
            'port' => $this->port,
377
            'user' => $this->user,
378
            'password' => $this->password,
379
            'path' => $this->path,
380
            'query' => $this->query,
381
            'fragment' => $this->fragment,
382
            'previous' => $this,
383
        ];
384
385
        $arguments = array_replace($defaultArguments, $arguments);
386
387
        return new self(...array_merge(array_values($arguments), [$this]));
0 ignored issues
show
Documentation introduced by
array_merge(array_values...guments), array($this)) is of type array<integer,?,{"0":"th...m\\HttpMessage\\Uri>"}>, but the function expects a null|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
388
    }
389
}
390