ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Uri.php
Go to the documentation of this file.
1<?php
9namespace Slim\Http;
10
11use InvalidArgumentException;
12use \Psr\Http\Message\UriInterface;
14
35class Uri implements UriInterface
36{
42 protected $scheme = '';
43
49 protected $user = '';
50
56 protected $password = '';
57
63 protected $host = '';
64
70 protected $port;
71
77 protected $basePath = '';
78
84 protected $path = '';
85
91 protected $query = '';
92
98 protected $fragment = '';
99
112 public function __construct(
113 $scheme,
114 $host,
115 $port = null,
116 $path = '/',
117 $query = '',
118 $fragment = '',
119 $user = '',
120 $password = ''
121 ) {
122 $this->scheme = $this->filterScheme($scheme);
123 $this->host = $host;
124 $this->port = $this->filterPort($port);
125 $this->path = empty($path) ? '/' : $this->filterPath($path);
126 $this->query = $this->filterQuery($query);
127 $this->fragment = $this->filterQuery($fragment);
128 $this->user = $user;
129 $this->password = $password;
130 }
131
140 public static function createFromString($uri)
141 {
142 if (!is_string($uri) && !method_exists($uri, '__toString')) {
143 throw new InvalidArgumentException('Uri must be a string');
144 }
145
146 $parts = parse_url($uri);
147 $scheme = isset($parts['scheme']) ? $parts['scheme'] : '';
148 $user = isset($parts['user']) ? $parts['user'] : '';
149 $pass = isset($parts['pass']) ? $parts['pass'] : '';
150 $host = isset($parts['host']) ? $parts['host'] : '';
151 $port = isset($parts['port']) ? $parts['port'] : null;
152 $path = isset($parts['path']) ? $parts['path'] : '';
153 $query = isset($parts['query']) ? $parts['query'] : '';
154 $fragment = isset($parts['fragment']) ? $parts['fragment'] : '';
155
156 return new static($scheme, $host, $port, $path, $query, $fragment, $user, $pass);
157 }
158
166 public static function createFromEnvironment(Environment $env)
167 {
168 // Scheme
169 $isSecure = $env->get('HTTPS');
170 $scheme = (empty($isSecure) || $isSecure === 'off') ? 'http' : 'https';
171
172 // Authority: Username and password
173 $username = $env->get('PHP_AUTH_USER', '');
174 $password = $env->get('PHP_AUTH_PW', '');
175
176 // Authority: Host and Port
177 if ($env->has('HTTP_HOST')) {
178 $host = $env->get('HTTP_HOST');
179 // set a port default
180 $port = null;
181 } else {
182 $host = $env->get('SERVER_NAME');
183 // set a port default
184 $port = (int)$env->get('SERVER_PORT', 80);
185 }
186
187 if (preg_match('/^(\[[a-fA-F0-9:.]+\])(:\d+)?\z/', $host, $matches)) {
188 $host = $matches[1];
189
190 if (isset($matches[2])) {
191 $port = (int) substr($matches[2], 1);
192 }
193 } else {
194 $pos = strpos($host, ':');
195 if ($pos !== false) {
196 $port = (int) substr($host, $pos + 1);
197 $host = strstr($host, ':', true);
198 }
199 }
200
201 // Path
202 $requestScriptName = parse_url($env->get('SCRIPT_NAME'), PHP_URL_PATH);
203 $requestScriptDir = dirname($requestScriptName);
204
205 // parse_url() requires a full URL. As we don't extract the domain name or scheme,
206 // we use a stand-in.
207 $requestUri = parse_url('http://example.com' . $env->get('REQUEST_URI'), PHP_URL_PATH);
208
209 $basePath = '';
210 $virtualPath = $requestUri;
211 if (stripos($requestUri, $requestScriptName) === 0) {
212 $basePath = $requestScriptName;
213 } elseif ($requestScriptDir !== '/' && stripos($requestUri, $requestScriptDir) === 0) {
214 $basePath = $requestScriptDir;
215 }
216
217 if ($basePath) {
218 $virtualPath = ltrim(substr($requestUri, strlen($basePath)), '/');
219 }
220
221 // Query string
222 $queryString = $env->get('QUERY_STRING', '');
223 if ($queryString === '') {
224 $queryString = parse_url('http://example.com' . $env->get('REQUEST_URI'), PHP_URL_QUERY);
225 }
226
227 // Fragment
228 $fragment = '';
229
230 // Build Uri
231 $uri = new static($scheme, $host, $port, $virtualPath, $queryString, $fragment, $username, $password);
232 if ($basePath) {
233 $uri = $uri->withBasePath($basePath);
234 }
235
236 return $uri;
237 }
238
239 /********************************************************************************
240 * Scheme
241 *******************************************************************************/
242
257 public function getScheme()
258 {
259 return $this->scheme;
260 }
261
277 public function withScheme($scheme)
278 {
279 $scheme = $this->filterScheme($scheme);
280 $clone = clone $this;
281 $clone->scheme = $scheme;
282
283 return $clone;
284 }
285
295 protected function filterScheme($scheme)
296 {
297 static $valid = [
298 '' => true,
299 'https' => true,
300 'http' => true,
301 ];
302
303 if (!is_string($scheme) && !method_exists($scheme, '__toString')) {
304 throw new InvalidArgumentException('Uri scheme must be a string');
305 }
306
307 $scheme = str_replace('://', '', strtolower((string)$scheme));
308 if (!isset($valid[$scheme])) {
309 throw new InvalidArgumentException('Uri scheme must be one of: "", "https", "http"');
310 }
311
312 return $scheme;
313 }
314
315 /********************************************************************************
316 * Authority
317 *******************************************************************************/
318
337 public function getAuthority()
338 {
339 $userInfo = $this->getUserInfo();
340 $host = $this->getHost();
341 $port = $this->getPort();
342
343 return ($userInfo !== '' ? $userInfo . '@' : '') . $host . ($port !== null ? ':' . $port : '');
344 }
345
361 public function getUserInfo()
362 {
363 return $this->user . ($this->password !== '' ? ':' . $this->password : '');
364 }
365
380 public function withUserInfo($user, $password = null)
381 {
382 $clone = clone $this;
383 $clone->user = $this->filterUserInfo($user);
384 if ('' !== $clone->user) {
385 $clone->password = !in_array($password, [null, ''], true) ? $this->filterUserInfo($password) : '';
386 } else {
387 $clone->password = '';
388 }
389
390 return $clone;
391 }
392
399 protected function filterUserInfo($query)
400 {
401 return preg_replace_callback(
402 '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\‍(\‍)\*\+,;=]+|%(?![A-Fa-f0-9]{2}))/u',
403 function ($match) {
404 return rawurlencode($match[0]);
405 },
406 $query
407 );
408 }
409
421 public function getHost()
422 {
423 return $this->host;
424 }
425
438 public function withHost($host)
439 {
440 $clone = clone $this;
441 $clone->host = $host;
442
443 return $clone;
444 }
445
461 public function getPort()
462 {
463 return $this->port && !$this->hasStandardPort() ? $this->port : null;
464 }
465
483 public function withPort($port)
484 {
485 $port = $this->filterPort($port);
486 $clone = clone $this;
487 $clone->port = $port;
488
489 return $clone;
490 }
491
497 protected function hasStandardPort()
498 {
499 return ($this->scheme === 'http' && $this->port === 80) || ($this->scheme === 'https' && $this->port === 443);
500 }
501
510 protected function filterPort($port)
511 {
512 if (is_null($port) || (is_integer($port) && ($port >= 1 && $port <= 65535))) {
513 return $port;
514 }
515
516 throw new InvalidArgumentException('Uri port must be null or an integer between 1 and 65535 (inclusive)');
517 }
518
519 /********************************************************************************
520 * Path
521 *******************************************************************************/
522
548 public function getPath()
549 {
550 return $this->path;
551 }
552
575 public function withPath($path)
576 {
577 if (!is_string($path)) {
578 throw new InvalidArgumentException('Uri path must be a string');
579 }
580
581 $clone = clone $this;
582 $clone->path = $this->filterPath($path);
583
584 // if the path is absolute, then clear basePath
585 if (substr($path, 0, 1) == '/') {
586 $clone->basePath = '';
587 }
588
589 return $clone;
590 }
591
602 public function getBasePath()
603 {
604 return $this->basePath;
605 }
606
615 public function withBasePath($basePath)
616 {
617 if (!is_string($basePath)) {
618 throw new InvalidArgumentException('Uri path must be a string');
619 }
620 if (!empty($basePath)) {
621 $basePath = '/' . trim($basePath, '/'); // <-- Trim on both sides
622 }
623 $clone = clone $this;
624
625 if ($basePath !== '/') {
626 $clone->basePath = $this->filterPath($basePath);
627 }
628
629 return $clone;
630 }
631
644 protected function filterPath($path)
645 {
646 return preg_replace_callback(
647 '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/',
648 function ($match) {
649 return rawurlencode($match[0]);
650 },
651 $path
652 );
653 }
654
655 /********************************************************************************
656 * Query
657 *******************************************************************************/
658
679 public function getQuery()
680 {
681 return $this->query;
682 }
683
699 public function withQuery($query)
700 {
701 if (!is_string($query) && !method_exists($query, '__toString')) {
702 throw new InvalidArgumentException('Uri query must be a string');
703 }
704 $query = ltrim((string)$query, '?');
705 $clone = clone $this;
706 $clone->query = $this->filterQuery($query);
707
708 return $clone;
709 }
710
717 protected function filterQuery($query)
718 {
719 return preg_replace_callback(
720 '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\‍(\‍)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/',
721 function ($match) {
722 return rawurlencode($match[0]);
723 },
724 $query
725 );
726 }
727
728 /********************************************************************************
729 * Fragment
730 *******************************************************************************/
731
748 public function getFragment()
749 {
750 return $this->fragment;
751 }
752
767 public function withFragment($fragment)
768 {
769 if (!is_string($fragment) && !method_exists($fragment, '__toString')) {
770 throw new InvalidArgumentException('Uri fragment must be a string');
771 }
772 $fragment = ltrim((string)$fragment, '#');
773 $clone = clone $this;
774 $clone->fragment = $this->filterQuery($fragment);
775
776 return $clone;
777 }
778
779 /********************************************************************************
780 * Helpers
781 *******************************************************************************/
782
806 public function __toString()
807 {
808 $scheme = $this->getScheme();
809 $authority = $this->getAuthority();
810 $basePath = $this->getBasePath();
811 $path = $this->getPath();
812 $query = $this->getQuery();
813 $fragment = $this->getFragment();
814
815 $path = $basePath . '/' . ltrim($path, '/');
816
817 return ($scheme !== '' ? $scheme . ':' : '')
818 . ($authority !== '' ? '//' . $authority : '')
819 . $path
820 . ($query !== '' ? '?' . $query : '')
821 . ($fragment !== '' ? '#' . $fragment : '');
822 }
823
833 public function getBaseUrl()
834 {
835 $scheme = $this->getScheme();
836 $authority = $this->getAuthority();
837 $basePath = $this->getBasePath();
838
839 if ($authority !== '' && substr($basePath, 0, 1) !== '/') {
840 $basePath = $basePath . '/' . $basePath;
841 }
842
843 return ($scheme !== '' ? $scheme . ':' : '')
844 . ($authority ? '//' . $authority : '')
845 . rtrim($basePath, '/');
846 }
847}
user()
Definition: user.php:4
$env
An exception for terminatinating execution or to throw for unit testing.
Value object representing a URI.
Definition: Uri.php:36
static createFromString($uri)
Create new Uri from string.
Definition: Uri.php:140
getAuthority()
Retrieve the authority component of the URI.
Definition: Uri.php:337
withPath($path)
Return an instance with the specified path.
Definition: Uri.php:575
withFragment($fragment)
Return an instance with the specified URI fragment.
Definition: Uri.php:767
getPath()
Retrieve the path component of the URI.
Definition: Uri.php:548
__construct( $scheme, $host, $port=null, $path='/', $query='', $fragment='', $user='', $password='')
Create new Uri.
Definition: Uri.php:112
filterPort($port)
Filter Uri port.
Definition: Uri.php:510
withBasePath($basePath)
Set base path.
Definition: Uri.php:615
getScheme()
Retrieve the scheme component of the URI.
Definition: Uri.php:257
getFragment()
Retrieve the fragment component of the URI.
Definition: Uri.php:748
hasStandardPort()
Does this Uri use a standard port?
Definition: Uri.php:497
filterScheme($scheme)
Filter Uri scheme.
Definition: Uri.php:295
withHost($host)
Return an instance with the specified host.
Definition: Uri.php:438
getPort()
Retrieve the port component of the URI.
Definition: Uri.php:461
withUserInfo($user, $password=null)
Return an instance with the specified user information.
Definition: Uri.php:380
getHost()
Retrieve the host component of the URI.
Definition: Uri.php:421
__toString()
Return the string representation as a URI reference.
Definition: Uri.php:806
withQuery($query)
Return an instance with the specified query string.
Definition: Uri.php:699
filterPath($path)
Filter Uri path.
Definition: Uri.php:644
withScheme($scheme)
Return an instance with the specified scheme.
Definition: Uri.php:277
static createFromEnvironment(Environment $env)
Create new Uri from environment.
Definition: Uri.php:166
withPort($port)
Return an instance with the specified port.
Definition: Uri.php:483
getQuery()
Retrieve the query string of the URI.
Definition: Uri.php:679
getUserInfo()
Retrieve the user information component of the URI.
Definition: Uri.php:361
filterQuery($query)
Filters the query string or fragment of a URI.
Definition: Uri.php:717
getBasePath()
Retrieve the base path segment of the URI.
Definition: Uri.php:602
filterUserInfo($query)
Filters the user info string.
Definition: Uri.php:399
getBaseUrl()
Return the fully qualified base URL.
Definition: Uri.php:833
$authority
$valid
Value object representing a URI.
Slim Framework (https://slimframework.com)
Definition: Body.php:9