ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
Uri.php
Go to the documentation of this file.
1<?php
2namespace GuzzleHttp\Psr7;
3
5
13class Uri implements UriInterface
14{
21 const HTTP_DEFAULT_HOST = 'localhost';
22
23 private static $defaultPorts = [
24 'http' => 80,
25 'https' => 443,
26 'ftp' => 21,
27 'gopher' => 70,
28 'nntp' => 119,
29 'news' => 119,
30 'telnet' => 23,
31 'tn3270' => 23,
32 'imap' => 143,
33 'pop' => 110,
34 'ldap' => 389,
35 ];
36
37 private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
38 private static $charSubDelims = '!\$&\'\‍(\‍)\*\+,;=';
39 private static $replaceQuery = ['=' => '%3D', '&' => '%26'];
40
42 private $scheme = '';
43
45 private $userInfo = '';
46
48 private $host = '';
49
51 private $port;
52
54 private $path = '';
55
57 private $query = '';
58
60 private $fragment = '';
61
65 public function __construct($uri = '')
66 {
67 // weak type check to also accept null until we can add scalar type hints
68 if ($uri != '') {
69 $parts = parse_url($uri);
70 if ($parts === false) {
71 throw new \InvalidArgumentException("Unable to parse URI: $uri");
72 }
73 $this->applyParts($parts);
74 }
75 }
76
77 public function __toString()
78 {
80 $this->scheme,
81 $this->getAuthority(),
82 $this->path,
83 $this->query,
84 $this->fragment
85 );
86 }
87
115 {
116 $uri = '';
117
118 // weak type checks to also accept null until we can add scalar type hints
119 if ($scheme != '') {
120 $uri .= $scheme . ':';
121 }
122
123 if ($authority != ''|| $scheme === 'file') {
124 $uri .= '//' . $authority;
125 }
126
127 $uri .= $path;
128
129 if ($query != '') {
130 $uri .= '?' . $query;
131 }
132
133 if ($fragment != '') {
134 $uri .= '#' . $fragment;
135 }
136
137 return $uri;
138 }
139
150 public static function isDefaultPort(UriInterface $uri)
151 {
152 return $uri->getPort() === null
153 || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]);
154 }
155
174 public static function isAbsolute(UriInterface $uri)
175 {
176 return $uri->getScheme() !== '';
177 }
178
189 public static function isNetworkPathReference(UriInterface $uri)
190 {
191 return $uri->getScheme() === '' && $uri->getAuthority() !== '';
192 }
193
204 public static function isAbsolutePathReference(UriInterface $uri)
205 {
206 return $uri->getScheme() === ''
207 && $uri->getAuthority() === ''
208 && isset($uri->getPath()[0])
209 && $uri->getPath()[0] === '/';
210 }
211
222 public static function isRelativePathReference(UriInterface $uri)
223 {
224 return $uri->getScheme() === ''
225 && $uri->getAuthority() === ''
226 && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
227 }
228
242 public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
243 {
244 if ($base !== null) {
245 $uri = UriResolver::resolve($base, $uri);
246
247 return ($uri->getScheme() === $base->getScheme())
248 && ($uri->getAuthority() === $base->getAuthority())
249 && ($uri->getPath() === $base->getPath())
250 && ($uri->getQuery() === $base->getQuery());
251 }
252
253 return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
254 }
255
266 public static function removeDotSegments($path)
267 {
269 }
270
282 public static function resolve(UriInterface $base, $rel)
283 {
284 if (!($rel instanceof UriInterface)) {
285 $rel = new self($rel);
286 }
287
288 return UriResolver::resolve($base, $rel);
289 }
290
302 public static function withoutQueryValue(UriInterface $uri, $key)
303 {
304 $current = $uri->getQuery();
305 if ($current === '') {
306 return $uri;
307 }
308
309 $decodedKey = rawurldecode($key);
310 $result = array_filter(explode('&', $current), function ($part) use ($decodedKey) {
311 return rawurldecode(explode('=', $part)[0]) !== $decodedKey;
312 });
313
314 return $uri->withQuery(implode('&', $result));
315 }
316
332 public static function withQueryValue(UriInterface $uri, $key, $value)
333 {
334 $current = $uri->getQuery();
335
336 if ($current === '') {
337 $result = [];
338 } else {
339 $decodedKey = rawurldecode($key);
340 $result = array_filter(explode('&', $current), function ($part) use ($decodedKey) {
341 return rawurldecode(explode('=', $part)[0]) !== $decodedKey;
342 });
343 }
344
345 // Query string separators ("=", "&") within the key or value need to be encoded
346 // (while preventing double-encoding) before setting the query string. All other
347 // chars that need percent-encoding will be encoded by withQuery().
348 $key = strtr($key, self::$replaceQuery);
349
350 if ($value !== null) {
351 $result[] = $key . '=' . strtr($value, self::$replaceQuery);
352 } else {
353 $result[] = $key;
354 }
355
356 return $uri->withQuery(implode('&', $result));
357 }
358
369 public static function fromParts(array $parts)
370 {
371 $uri = new self();
372 $uri->applyParts($parts);
373 $uri->validateState();
374
375 return $uri;
376 }
377
378 public function getScheme()
379 {
380 return $this->scheme;
381 }
382
383 public function getAuthority()
384 {
386 if ($this->userInfo !== '') {
387 $authority = $this->userInfo . '@' . $authority;
388 }
389
390 if ($this->port !== null) {
391 $authority .= ':' . $this->port;
392 }
393
394 return $authority;
395 }
396
397 public function getUserInfo()
398 {
399 return $this->userInfo;
400 }
401
402 public function getHost()
403 {
404 return $this->host;
405 }
406
407 public function getPort()
408 {
409 return $this->port;
410 }
411
412 public function getPath()
413 {
414 return $this->path;
415 }
416
417 public function getQuery()
418 {
419 return $this->query;
420 }
421
422 public function getFragment()
423 {
424 return $this->fragment;
425 }
426
427 public function withScheme($scheme)
428 {
429 $scheme = $this->filterScheme($scheme);
430
431 if ($this->scheme === $scheme) {
432 return $this;
433 }
434
435 $new = clone $this;
436 $new->scheme = $scheme;
437 $new->removeDefaultPort();
438 $new->validateState();
439
440 return $new;
441 }
442
443 public function withUserInfo($user, $password = null)
444 {
445 $info = $user;
446 if ($password != '') {
447 $info .= ':' . $password;
448 }
449
450 if ($this->userInfo === $info) {
451 return $this;
452 }
453
454 $new = clone $this;
455 $new->userInfo = $info;
456 $new->validateState();
457
458 return $new;
459 }
460
461 public function withHost($host)
462 {
463 $host = $this->filterHost($host);
464
465 if ($this->host === $host) {
466 return $this;
467 }
468
469 $new = clone $this;
470 $new->host = $host;
471 $new->validateState();
472
473 return $new;
474 }
475
476 public function withPort($port)
477 {
478 $port = $this->filterPort($port);
479
480 if ($this->port === $port) {
481 return $this;
482 }
483
484 $new = clone $this;
485 $new->port = $port;
486 $new->removeDefaultPort();
487 $new->validateState();
488
489 return $new;
490 }
491
492 public function withPath($path)
493 {
494 $path = $this->filterPath($path);
495
496 if ($this->path === $path) {
497 return $this;
498 }
499
500 $new = clone $this;
501 $new->path = $path;
502 $new->validateState();
503
504 return $new;
505 }
506
507 public function withQuery($query)
508 {
510
511 if ($this->query === $query) {
512 return $this;
513 }
514
515 $new = clone $this;
516 $new->query = $query;
517
518 return $new;
519 }
520
521 public function withFragment($fragment)
522 {
524
525 if ($this->fragment === $fragment) {
526 return $this;
527 }
528
529 $new = clone $this;
530 $new->fragment = $fragment;
531
532 return $new;
533 }
534
540 private function applyParts(array $parts)
541 {
542 $this->scheme = isset($parts['scheme'])
543 ? $this->filterScheme($parts['scheme'])
544 : '';
545 $this->userInfo = isset($parts['user']) ? $parts['user'] : '';
546 $this->host = isset($parts['host'])
547 ? $this->filterHost($parts['host'])
548 : '';
549 $this->port = isset($parts['port'])
550 ? $this->filterPort($parts['port'])
551 : null;
552 $this->path = isset($parts['path'])
553 ? $this->filterPath($parts['path'])
554 : '';
555 $this->query = isset($parts['query'])
556 ? $this->filterQueryAndFragment($parts['query'])
557 : '';
558 $this->fragment = isset($parts['fragment'])
559 ? $this->filterQueryAndFragment($parts['fragment'])
560 : '';
561 if (isset($parts['pass'])) {
562 $this->userInfo .= ':' . $parts['pass'];
563 }
564
565 $this->removeDefaultPort();
566 }
567
575 private function filterScheme($scheme)
576 {
577 if (!is_string($scheme)) {
578 throw new \InvalidArgumentException('Scheme must be a string');
579 }
580
581 return strtolower($scheme);
582 }
583
591 private function filterHost($host)
592 {
593 if (!is_string($host)) {
594 throw new \InvalidArgumentException('Host must be a string');
595 }
596
597 return strtolower($host);
598 }
599
607 private function filterPort($port)
608 {
609 if ($port === null) {
610 return null;
611 }
612
613 $port = (int) $port;
614 if (1 > $port || 0xffff < $port) {
615 throw new \InvalidArgumentException(
616 sprintf('Invalid port: %d. Must be between 1 and 65535', $port)
617 );
618 }
619
620 return $port;
621 }
622
623 private function removeDefaultPort()
624 {
625 if ($this->port !== null && self::isDefaultPort($this)) {
626 $this->port = null;
627 }
628 }
629
639 private function filterPath($path)
640 {
641 if (!is_string($path)) {
642 throw new \InvalidArgumentException('Path must be a string');
643 }
644
645 return preg_replace_callback(
646 '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
647 [$this, 'rawurlencodeMatchZero'],
648 $path
649 );
650 }
651
661 private function filterQueryAndFragment($str)
662 {
663 if (!is_string($str)) {
664 throw new \InvalidArgumentException('Query and fragment must be a string');
665 }
666
667 return preg_replace_callback(
668 '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
669 [$this, 'rawurlencodeMatchZero'],
670 $str
671 );
672 }
673
674 private function rawurlencodeMatchZero(array $match)
675 {
676 return rawurlencode($match[0]);
677 }
678
679 private function validateState()
680 {
681 if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
682 $this->host = self::HTTP_DEFAULT_HOST;
683 }
684
685 if ($this->getAuthority() === '') {
686 if (0 === strpos($this->path, '//')) {
687 throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"');
688 }
689 if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
690 throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon');
691 }
692 } elseif (isset($this->path[0]) && $this->path[0] !== '/') {
693 @trigger_error(
694 'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' .
695 'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
696 E_USER_DEPRECATED
697 );
698 $this->path = '/'. $this->path;
699 //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty');
700 }
701 }
702}
sprintf('%.4f', $callTime)
$result
An exception for terminatinating execution or to throw for unit testing.
static removeDotSegments($path)
Removes dot segments from a path and returns the new path.
Definition: UriResolver.php:23
static resolve(UriInterface $base, UriInterface $rel)
Converts the relative URI into a new URI that is resolved against the base URI.
Definition: UriResolver.php:62
PSR-7 URI implementation.
Definition: Uri.php:14
getPath()
Retrieve the path component of the URI.
Definition: Uri.php:412
static isRelativePathReference(UriInterface $uri)
Whether the URI is a relative-path reference.
Definition: Uri.php:222
static isAbsolutePathReference(UriInterface $uri)
Whether the URI is a absolute-path reference.
Definition: Uri.php:204
getAuthority()
Retrieve the authority component of the URI.
Definition: Uri.php:383
filterHost($host)
Definition: Uri.php:591
static resolve(UriInterface $base, $rel)
Converts the relative URI into a new URI that is resolved against the base URI.
Definition: Uri.php:282
getScheme()
Retrieve the scheme component of the URI.
Definition: Uri.php:378
static $replaceQuery
Definition: Uri.php:39
withFragment($fragment)
Return an instance with the specified URI fragment.
Definition: Uri.php:521
__construct($uri='')
Definition: Uri.php:65
static withoutQueryValue(UriInterface $uri, $key)
Creates a new URI with a specific query string value removed.
Definition: Uri.php:302
applyParts(array $parts)
Apply parse_url parts to a URI.
Definition: Uri.php:540
filterPath($path)
Filters the path of a URI.
Definition: Uri.php:639
static fromParts(array $parts)
Creates a URI from a hash of parse_url components.
Definition: Uri.php:369
static composeComponents($scheme, $authority, $path, $query, $fragment)
Composes a URI reference string from its various components.
Definition: Uri.php:114
filterQueryAndFragment($str)
Filters the query string or fragment of a URI.
Definition: Uri.php:661
withHost($host)
Return an instance with the specified host.
Definition: Uri.php:461
getQuery()
Retrieve the query string of the URI.
Definition: Uri.php:417
static withQueryValue(UriInterface $uri, $key, $value)
Creates a new URI with a specific query string value.
Definition: Uri.php:332
getHost()
Retrieve the host component of the URI.
Definition: Uri.php:402
withQuery($query)
Return an instance with the specified query string.
Definition: Uri.php:507
static $charUnreserved
Definition: Uri.php:37
withPath($path)
Return an instance with the specified path.
Definition: Uri.php:492
static isSameDocumentReference(UriInterface $uri, UriInterface $base=null)
Whether the URI is a same-document reference.
Definition: Uri.php:242
rawurlencodeMatchZero(array $match)
Definition: Uri.php:674
__toString()
Return the string representation as a URI reference.
Definition: Uri.php:77
static $defaultPorts
Definition: Uri.php:23
static isDefaultPort(UriInterface $uri)
Whether the URI has the default port of the current scheme.
Definition: Uri.php:150
getUserInfo()
Retrieve the user information component of the URI.
Definition: Uri.php:397
getPort()
Retrieve the port component of the URI.
Definition: Uri.php:407
withScheme($scheme)
Return an instance with the specified scheme.
Definition: Uri.php:427
static isNetworkPathReference(UriInterface $uri)
Whether the URI is a network-path reference.
Definition: Uri.php:189
const HTTP_DEFAULT_HOST
Absolute http and https URIs require a host per RFC 7230 Section 2.7 but in generic URIs the host can...
Definition: Uri.php:21
static $charSubDelims
Definition: Uri.php:38
static removeDotSegments($path)
Removes dot segments from a path and returns the new path.
Definition: Uri.php:266
static isAbsolute(UriInterface $uri)
Whether the URI is absolute, i.e.
Definition: Uri.php:174
withUserInfo($user, $password=null)
Return an instance with the specified user information.
Definition: Uri.php:443
getFragment()
Retrieve the fragment component of the URI.
Definition: Uri.php:422
withPort($port)
Return an instance with the specified port.
Definition: Uri.php:476
filterScheme($scheme)
Definition: Uri.php:575
filterPort($port)
Definition: Uri.php:607
$authority
$key
Definition: croninfo.php:18
Value object representing a URI.
getScheme()
Retrieve the scheme component of the URI.
getAuthority()
Retrieve the authority component of the URI.
withQuery($query)
Return an instance with the specified query string.
getQuery()
Retrieve the query string of the URI.
getPath()
Retrieve the path component of the URI.
getPort()
Retrieve the port component of the URI.
$base
Definition: index.php:4
$info
Definition: index.php:5
$password
Definition: pwgen.php:17