class Uri in Zircon Profile 8.0
Same name in this branch
- 8.0 vendor/zendframework/zend-diactoros/src/Uri.php \Zend\Diactoros\Uri
- 8.0 vendor/zendframework/zend-feed/src/Uri.php \Zend\Feed\Uri
- 8.0 vendor/guzzlehttp/psr7/src/Uri.php \GuzzleHttp\Psr7\Uri
- 8.0 core/lib/Drupal/Core/TypedData/Plugin/DataType/Uri.php \Drupal\Core\TypedData\Plugin\DataType\Uri
Same name and namespace in other branches
- 8 vendor/zendframework/zend-diactoros/src/Uri.php \Zend\Diactoros\Uri
Implementation of Psr\Http\UriInterface.
Provides a value object representing a URI for HTTP requests.
Instances of this class are considered immutable; all methods that might change state are implemented such that they retain the internal state of the current instance and return a new instance that contains the changed state.
Hierarchy
- class \Zend\Diactoros\Uri implements UriInterface
Expanded class hierarchy of Uri
2 files declare their use of Uri
- Serializer.php in vendor/
zendframework/ zend-diactoros/ src/ Request/ Serializer.php - WebTestBase.php in core/
modules/ simpletest/ src/ WebTestBase.php - Contains \Drupal\simpletest\WebTestBase.
1 string reference to 'Uri'
- core.data_types.schema.yml in core/
config/ schema/ core.data_types.schema.yml - core/config/schema/core.data_types.schema.yml
File
- vendor/
zendframework/ zend-diactoros/ src/ Uri.php, line 25
Namespace
Zend\DiactorosView source
class Uri implements UriInterface {
/**
* Sub-delimiters used in query strings and fragments.
*
* @const string
*/
const CHAR_SUB_DELIMS = '!\\$&\'\\(\\)\\*\\+,;=';
/**
* Unreserved characters used in paths, query strings, and fragments.
*
* @const string
*/
const CHAR_UNRESERVED = 'a-zA-Z0-9_\\-\\.~';
/**
* @var int[] Array indexed by valid scheme names to their corresponding ports.
*/
protected $allowedSchemes = [
'http' => 80,
'https' => 443,
];
/**
* @var string
*/
private $scheme = '';
/**
* @var string
*/
private $userInfo = '';
/**
* @var string
*/
private $host = '';
/**
* @var int
*/
private $port;
/**
* @var string
*/
private $path = '';
/**
* @var string
*/
private $query = '';
/**
* @var string
*/
private $fragment = '';
/**
* generated uri string cache
* @var string|null
*/
private $uriString;
/**
* @param string $uri
* @throws InvalidArgumentException on non-string $uri argument
*/
public function __construct($uri = '') {
if (!is_string($uri)) {
throw new InvalidArgumentException(sprintf('URI passed to constructor must be a string; received "%s"', is_object($uri) ? get_class($uri) : gettype($uri)));
}
if (!empty($uri)) {
$this
->parseUri($uri);
}
}
/**
* Operations to perform on clone.
*
* Since cloning usually is for purposes of mutation, we reset the
* $uriString property so it will be re-calculated.
*/
public function __clone() {
$this->uriString = null;
}
/**
* {@inheritdoc}
*/
public function __toString() {
if (null !== $this->uriString) {
return $this->uriString;
}
$this->uriString = static::createUriString($this->scheme, $this
->getAuthority(), $this
->getPath(), $this->query, $this->fragment);
return $this->uriString;
}
/**
* {@inheritdoc}
*/
public function getScheme() {
return $this->scheme;
}
/**
* {@inheritdoc}
*/
public function getAuthority() {
if (empty($this->host)) {
return '';
}
$authority = $this->host;
if (!empty($this->userInfo)) {
$authority = $this->userInfo . '@' . $authority;
}
if ($this
->isNonStandardPort($this->scheme, $this->host, $this->port)) {
$authority .= ':' . $this->port;
}
return $authority;
}
/**
* {@inheritdoc}
*/
public function getUserInfo() {
return $this->userInfo;
}
/**
* {@inheritdoc}
*/
public function getHost() {
return $this->host;
}
/**
* {@inheritdoc}
*/
public function getPort() {
return $this
->isNonStandardPort($this->scheme, $this->host, $this->port) ? $this->port : null;
}
/**
* {@inheritdoc}
*/
public function getPath() {
return $this->path;
}
/**
* {@inheritdoc}
*/
public function getQuery() {
return $this->query;
}
/**
* {@inheritdoc}
*/
public function getFragment() {
return $this->fragment;
}
/**
* {@inheritdoc}
*/
public function withScheme($scheme) {
if (!is_string($scheme)) {
throw new InvalidArgumentException(sprintf('%s expects a string argument; received %s', __METHOD__, is_object($scheme) ? get_class($scheme) : gettype($scheme)));
}
$scheme = $this
->filterScheme($scheme);
if ($scheme === $this->scheme) {
// Do nothing if no change was made.
return clone $this;
}
$new = clone $this;
$new->scheme = $scheme;
return $new;
}
/**
* {@inheritdoc}
*/
public function withUserInfo($user, $password = null) {
if (!is_string($user)) {
throw new InvalidArgumentException(sprintf('%s expects a string user argument; received %s', __METHOD__, is_object($user) ? get_class($user) : gettype($user)));
}
if (null !== $password && !is_string($password)) {
throw new InvalidArgumentException(sprintf('%s expects a string password argument; received %s', __METHOD__, is_object($password) ? get_class($password) : gettype($password)));
}
$info = $user;
if ($password) {
$info .= ':' . $password;
}
if ($info === $this->userInfo) {
// Do nothing if no change was made.
return clone $this;
}
$new = clone $this;
$new->userInfo = $info;
return $new;
}
/**
* {@inheritdoc}
*/
public function withHost($host) {
if (!is_string($host)) {
throw new InvalidArgumentException(sprintf('%s expects a string argument; received %s', __METHOD__, is_object($host) ? get_class($host) : gettype($host)));
}
if ($host === $this->host) {
// Do nothing if no change was made.
return clone $this;
}
$new = clone $this;
$new->host = $host;
return $new;
}
/**
* {@inheritdoc}
*/
public function withPort($port) {
if (!is_numeric($port)) {
throw new InvalidArgumentException(sprintf('Invalid port "%s" specified; must be an integer or integer string', is_object($port) ? get_class($port) : gettype($port)));
}
$port = (int) $port;
if ($port === $this->port) {
// Do nothing if no change was made.
return clone $this;
}
if ($port < 1 || $port > 65535) {
throw new InvalidArgumentException(sprintf('Invalid port "%d" specified; must be a valid TCP/UDP port', $port));
}
$new = clone $this;
$new->port = $port;
return $new;
}
/**
* {@inheritdoc}
*/
public function withPath($path) {
if (!is_string($path)) {
throw new InvalidArgumentException('Invalid path provided; must be a string');
}
if (strpos($path, '?') !== false) {
throw new InvalidArgumentException('Invalid path provided; must not contain a query string');
}
if (strpos($path, '#') !== false) {
throw new InvalidArgumentException('Invalid path provided; must not contain a URI fragment');
}
$path = $this
->filterPath($path);
if ($path === $this->path) {
// Do nothing if no change was made.
return clone $this;
}
$new = clone $this;
$new->path = $path;
return $new;
}
/**
* {@inheritdoc}
*/
public function withQuery($query) {
if (!is_string($query)) {
throw new InvalidArgumentException('Query string must be a string');
}
if (strpos($query, '#') !== false) {
throw new InvalidArgumentException('Query string must not include a URI fragment');
}
$query = $this
->filterQuery($query);
if ($query === $this->query) {
// Do nothing if no change was made.
return clone $this;
}
$new = clone $this;
$new->query = $query;
return $new;
}
/**
* {@inheritdoc}
*/
public function withFragment($fragment) {
if (!is_string($fragment)) {
throw new InvalidArgumentException(sprintf('%s expects a string argument; received %s', __METHOD__, is_object($fragment) ? get_class($fragment) : gettype($fragment)));
}
$fragment = $this
->filterFragment($fragment);
if ($fragment === $this->fragment) {
// Do nothing if no change was made.
return clone $this;
}
$new = clone $this;
$new->fragment = $fragment;
return $new;
}
/**
* Parse a URI into its parts, and set the properties
*
* @param string $uri
*/
private function parseUri($uri) {
$parts = parse_url($uri);
if (false === $parts) {
throw new \InvalidArgumentException('The source URI string appears to be malformed');
}
$this->scheme = isset($parts['scheme']) ? $this
->filterScheme($parts['scheme']) : '';
$this->userInfo = isset($parts['user']) ? $parts['user'] : '';
$this->host = isset($parts['host']) ? $parts['host'] : '';
$this->port = isset($parts['port']) ? $parts['port'] : null;
$this->path = isset($parts['path']) ? $this
->filterPath($parts['path']) : '';
$this->query = isset($parts['query']) ? $this
->filterQuery($parts['query']) : '';
$this->fragment = isset($parts['fragment']) ? $this
->filterFragment($parts['fragment']) : '';
if (isset($parts['pass'])) {
$this->userInfo .= ':' . $parts['pass'];
}
}
/**
* Create a URI string from its various parts
*
* @param string $scheme
* @param string $authority
* @param string $path
* @param string $query
* @param string $fragment
* @return string
*/
private static function createUriString($scheme, $authority, $path, $query, $fragment) {
$uri = '';
if (!empty($scheme)) {
$uri .= sprintf('%s://', $scheme);
}
if (!empty($authority)) {
$uri .= $authority;
}
if ($path) {
if (empty($path) || '/' !== substr($path, 0, 1)) {
$path = '/' . $path;
}
$uri .= $path;
}
if ($query) {
$uri .= sprintf('?%s', $query);
}
if ($fragment) {
$uri .= sprintf('#%s', $fragment);
}
return $uri;
}
/**
* Is a given port non-standard for the current scheme?
*
* @param string $scheme
* @param string $host
* @param int $port
* @return bool
*/
private function isNonStandardPort($scheme, $host, $port) {
if (!$scheme) {
return true;
}
if (!$host || !$port) {
return false;
}
return !isset($this->allowedSchemes[$scheme]) || $port !== $this->allowedSchemes[$scheme];
}
/**
* Filters the scheme to ensure it is a valid scheme.
*
* @param string $scheme Scheme name.
*
* @return string Filtered scheme.
*/
private function filterScheme($scheme) {
$scheme = strtolower($scheme);
$scheme = preg_replace('#:(//)?$#', '', $scheme);
if (empty($scheme)) {
return '';
}
if (!array_key_exists($scheme, $this->allowedSchemes)) {
throw new InvalidArgumentException(sprintf('Unsupported scheme "%s"; must be any empty string or in the set (%s)', $scheme, implode(', ', array_keys($this->allowedSchemes))));
}
return $scheme;
}
/**
* Filters the path of a URI to ensure it is properly encoded.
*
* @param string $path
* @return string
*/
private function filterPath($path) {
$path = preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . ':@&=\\+\\$,\\/;%]+|%(?![A-Fa-f0-9]{2}))/', [
$this,
'urlEncodeChar',
], $path);
if (empty($path)) {
// No path
return $path;
}
if ($path[0] !== '/') {
// Relative path
return $path;
}
// Ensure only one leading slash, to prevent XSS attempts.
return '/' . ltrim($path, '/');
}
/**
* Filter a query string to ensure it is propertly encoded.
*
* Ensures that the values in the query string are properly urlencoded.
*
* @param string $query
* @return string
*/
private function filterQuery($query) {
if (!empty($query) && strpos($query, '?') === 0) {
$query = substr($query, 1);
}
$parts = explode('&', $query);
foreach ($parts as $index => $part) {
list($key, $value) = $this
->splitQueryValue($part);
if ($value === null) {
$parts[$index] = $this
->filterQueryOrFragment($key);
continue;
}
$parts[$index] = sprintf('%s=%s', $this
->filterQueryOrFragment($key), $this
->filterQueryOrFragment($value));
}
return implode('&', $parts);
}
/**
* Split a query value into a key/value tuple.
*
* @param string $value
* @return array A value with exactly two elements, key and value
*/
private function splitQueryValue($value) {
$data = explode('=', $value, 2);
if (1 === count($data)) {
$data[] = null;
}
return $data;
}
/**
* Filter a fragment value to ensure it is properly encoded.
*
* @param null|string $fragment
* @return string
*/
private function filterFragment($fragment) {
if (!empty($fragment) && strpos($fragment, '#') === 0) {
$fragment = substr($fragment, 1);
}
return $this
->filterQueryOrFragment($fragment);
}
/**
* Filter a query string key or value, or a fragment.
*
* @param string $value
* @return string
*/
private function filterQueryOrFragment($value) {
return preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\\/\\?]+|%(?![A-Fa-f0-9]{2}))/', [
$this,
'urlEncodeChar',
], $value);
}
/**
* URL encode a character returned by a regex.
*
* @param array $matches
* @return string
*/
private function urlEncodeChar(array $matches) {
return rawurlencode($matches[0]);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Uri:: |
protected | property | ||
Uri:: |
private | property | ||
Uri:: |
private | property | ||
Uri:: |
private | property | ||
Uri:: |
private | property | ||
Uri:: |
private | property | ||
Uri:: |
private | property | ||
Uri:: |
private | property | generated uri string cache | |
Uri:: |
private | property | ||
Uri:: |
constant | Sub-delimiters used in query strings and fragments. | ||
Uri:: |
constant | Unreserved characters used in paths, query strings, and fragments. | ||
Uri:: |
private static | function | Create a URI string from its various parts | |
Uri:: |
private | function | Filter a fragment value to ensure it is properly encoded. | |
Uri:: |
private | function | Filters the path of a URI to ensure it is properly encoded. | |
Uri:: |
private | function | Filter a query string to ensure it is propertly encoded. | |
Uri:: |
private | function | Filter a query string key or value, or a fragment. | |
Uri:: |
private | function | Filters the scheme to ensure it is a valid scheme. | |
Uri:: |
public | function |
Retrieve the authority component of the URI. Overrides UriInterface:: |
|
Uri:: |
public | function |
Retrieve the fragment component of the URI. Overrides UriInterface:: |
|
Uri:: |
public | function |
Retrieve the host component of the URI. Overrides UriInterface:: |
|
Uri:: |
public | function |
Retrieve the path component of the URI. Overrides UriInterface:: |
|
Uri:: |
public | function |
Retrieve the port component of the URI. Overrides UriInterface:: |
|
Uri:: |
public | function |
Retrieve the query string of the URI. Overrides UriInterface:: |
|
Uri:: |
public | function |
Retrieve the scheme component of the URI. Overrides UriInterface:: |
|
Uri:: |
public | function |
Retrieve the user information component of the URI. Overrides UriInterface:: |
|
Uri:: |
private | function | Is a given port non-standard for the current scheme? | |
Uri:: |
private | function | Parse a URI into its parts, and set the properties | |
Uri:: |
private | function | Split a query value into a key/value tuple. | |
Uri:: |
private | function | URL encode a character returned by a regex. | |
Uri:: |
public | function |
Return an instance with the specified URI fragment. Overrides UriInterface:: |
|
Uri:: |
public | function |
Return an instance with the specified host. Overrides UriInterface:: |
|
Uri:: |
public | function |
Return an instance with the specified path. Overrides UriInterface:: |
|
Uri:: |
public | function |
Return an instance with the specified port. Overrides UriInterface:: |
|
Uri:: |
public | function |
Return an instance with the specified query string. Overrides UriInterface:: |
|
Uri:: |
public | function |
Return an instance with the specified scheme. Overrides UriInterface:: |
|
Uri:: |
public | function |
Return an instance with the specified user information. Overrides UriInterface:: |
|
Uri:: |
public | function | Operations to perform on clone. | |
Uri:: |
public | function | ||
Uri:: |
public | function |
Return the string representation as a URI reference. Overrides UriInterface:: |