ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Uri.php
Go to the documentation of this file.
1 <?php
9 namespace Slim\Http;
10 
12 use \Psr\Http\Message\UriInterface;
14 
35 class 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 }
filterPath($path)
Filter Uri path.
Definition: Uri.php:644
withQuery($query)
Return an instance with the specified query string.
Definition: Uri.php:699
filterQuery($query)
Filters the query string or fragment of a URI.
Definition: Uri.php:717
getFragment()
Retrieve the fragment component of the URI.
Definition: Uri.php:748
static createFromEnvironment(Environment $env)
Create new Uri from environment.
Definition: Uri.php:166
Value object representing a URI.
$valid
withScheme($scheme)
Return an instance with the specified scheme.
Definition: Uri.php:277
filterUserInfo($query)
Filters the user info string.
Definition: Uri.php:399
getBasePath()
Retrieve the base path segment of the URI.
Definition: Uri.php:602
getQuery()
Retrieve the query string of the URI.
Definition: Uri.php:679
filterPort($port)
Filter Uri port.
Definition: Uri.php:510
hasStandardPort()
Does this Uri use a standard port?
Definition: Uri.php:497
user()
Definition: user.php:4
static createFromString($uri)
Create new Uri from string.
Definition: Uri.php:140
get($key, $default=null)
Get collection item for key.
Definition: Collection.php:63
$env
getScheme()
Retrieve the scheme component of the URI.
Definition: Uri.php:257
getPort()
Retrieve the port component of the URI.
Definition: Uri.php:461
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
withUserInfo($user, $password=null)
Return an instance with the specified user information.
Definition: Uri.php:380
has($key)
Does this collection have a given key?
Definition: Collection.php:107
Slim Framework (https://slimframework.com)
Definition: Body.php:9
Value object representing a URI.
Definition: Uri.php:35
getBaseUrl()
Return the fully qualified base URL.
Definition: Uri.php:833
filterScheme($scheme)
Filter Uri scheme.
Definition: Uri.php:295
withFragment($fragment)
Return an instance with the specified URI fragment.
Definition: Uri.php:767
__construct( $scheme, $host, $port=null, $path='/', $query='', $fragment='', $user='', $password='')
Create new Uri.
Definition: Uri.php:112
withPort($port)
Return an instance with the specified port.
Definition: Uri.php:483
__toString()
Return the string representation as a URI reference.
Definition: Uri.php:806
getUserInfo()
Retrieve the user information component of the URI.
Definition: Uri.php:361
withBasePath($basePath)
Set base path.
Definition: Uri.php:615
withHost($host)
Return an instance with the specified host.
Definition: Uri.php:438
getPath()
Retrieve the path component of the URI.
Definition: Uri.php:548
getHost()
Retrieve the host component of the URI.
Definition: Uri.php:421
$authority