[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare(strict_types=1); 4 5 namespace Nyholm\Psr7; 6 7 use Psr\Http\Message\UriInterface; 8 9 /** 10 * PSR-7 URI implementation. 11 * 12 * @author Michael Dowling 13 * @author Tobias Schultze 14 * @author Matthew Weier O'Phinney 15 * @author Tobias Nyholm <[email protected]> 16 * @author Martijn van der Ven <[email protected]> 17 * 18 * @final This class should never be extended. See https://github.com/Nyholm/psr7/blob/master/doc/final.md 19 */ 20 class Uri implements UriInterface 21 { 22 private const SCHEMES = ['http' => 80, 'https' => 443]; 23 24 private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~'; 25 26 private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;='; 27 28 /** @var string Uri scheme. */ 29 private $scheme = ''; 30 31 /** @var string Uri user info. */ 32 private $userInfo = ''; 33 34 /** @var string Uri host. */ 35 private $host = ''; 36 37 /** @var int|null Uri port. */ 38 private $port; 39 40 /** @var string Uri path. */ 41 private $path = ''; 42 43 /** @var string Uri query string. */ 44 private $query = ''; 45 46 /** @var string Uri fragment. */ 47 private $fragment = ''; 48 49 public function __construct(string $uri = '') 50 { 51 if ('' !== $uri) { 52 if (false === $parts = \parse_url($uri)) { 53 throw new \InvalidArgumentException(\sprintf('Unable to parse URI: "%s"', $uri)); 54 } 55 56 // Apply parse_url parts to a URI. 57 $this->scheme = isset($parts['scheme']) ? \strtr($parts['scheme'], 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') : ''; 58 $this->userInfo = $parts['user'] ?? ''; 59 $this->host = isset($parts['host']) ? \strtr($parts['host'], 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') : ''; 60 $this->port = isset($parts['port']) ? $this->filterPort($parts['port']) : null; 61 $this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : ''; 62 $this->query = isset($parts['query']) ? $this->filterQueryAndFragment($parts['query']) : ''; 63 $this->fragment = isset($parts['fragment']) ? $this->filterQueryAndFragment($parts['fragment']) : ''; 64 if (isset($parts['pass'])) { 65 $this->userInfo .= ':' . $parts['pass']; 66 } 67 } 68 } 69 70 public function __toString(): string 71 { 72 return self::createUriString($this->scheme, $this->getAuthority(), $this->path, $this->query, $this->fragment); 73 } 74 75 public function getScheme(): string 76 { 77 return $this->scheme; 78 } 79 80 public function getAuthority(): string 81 { 82 if ('' === $this->host) { 83 return ''; 84 } 85 86 $authority = $this->host; 87 if ('' !== $this->userInfo) { 88 $authority = $this->userInfo . '@' . $authority; 89 } 90 91 if (null !== $this->port) { 92 $authority .= ':' . $this->port; 93 } 94 95 return $authority; 96 } 97 98 public function getUserInfo(): string 99 { 100 return $this->userInfo; 101 } 102 103 public function getHost(): string 104 { 105 return $this->host; 106 } 107 108 public function getPort(): ?int 109 { 110 return $this->port; 111 } 112 113 public function getPath(): string 114 { 115 return $this->path; 116 } 117 118 public function getQuery(): string 119 { 120 return $this->query; 121 } 122 123 public function getFragment(): string 124 { 125 return $this->fragment; 126 } 127 128 public function withScheme($scheme): self 129 { 130 if (!\is_string($scheme)) { 131 throw new \InvalidArgumentException('Scheme must be a string'); 132 } 133 134 if ($this->scheme === $scheme = \strtr($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')) { 135 return $this; 136 } 137 138 $new = clone $this; 139 $new->scheme = $scheme; 140 $new->port = $new->filterPort($new->port); 141 142 return $new; 143 } 144 145 public function withUserInfo($user, $password = null): self 146 { 147 $info = $user; 148 if (null !== $password && '' !== $password) { 149 $info .= ':' . $password; 150 } 151 152 if ($this->userInfo === $info) { 153 return $this; 154 } 155 156 $new = clone $this; 157 $new->userInfo = $info; 158 159 return $new; 160 } 161 162 public function withHost($host): self 163 { 164 if (!\is_string($host)) { 165 throw new \InvalidArgumentException('Host must be a string'); 166 } 167 168 if ($this->host === $host = \strtr($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')) { 169 return $this; 170 } 171 172 $new = clone $this; 173 $new->host = $host; 174 175 return $new; 176 } 177 178 public function withPort($port): self 179 { 180 if ($this->port === $port = $this->filterPort($port)) { 181 return $this; 182 } 183 184 $new = clone $this; 185 $new->port = $port; 186 187 return $new; 188 } 189 190 public function withPath($path): self 191 { 192 if ($this->path === $path = $this->filterPath($path)) { 193 return $this; 194 } 195 196 $new = clone $this; 197 $new->path = $path; 198 199 return $new; 200 } 201 202 public function withQuery($query): self 203 { 204 if ($this->query === $query = $this->filterQueryAndFragment($query)) { 205 return $this; 206 } 207 208 $new = clone $this; 209 $new->query = $query; 210 211 return $new; 212 } 213 214 public function withFragment($fragment): self 215 { 216 if ($this->fragment === $fragment = $this->filterQueryAndFragment($fragment)) { 217 return $this; 218 } 219 220 $new = clone $this; 221 $new->fragment = $fragment; 222 223 return $new; 224 } 225 226 /** 227 * Create a URI string from its various parts. 228 */ 229 private static function createUriString(string $scheme, string $authority, string $path, string $query, string $fragment): string 230 { 231 $uri = ''; 232 if ('' !== $scheme) { 233 $uri .= $scheme . ':'; 234 } 235 236 if ('' !== $authority) { 237 $uri .= '//' . $authority; 238 } 239 240 if ('' !== $path) { 241 if ('/' !== $path[0]) { 242 if ('' !== $authority) { 243 // If the path is rootless and an authority is present, the path MUST be prefixed by "/" 244 $path = '/' . $path; 245 } 246 } elseif (isset($path[1]) && '/' === $path[1]) { 247 if ('' === $authority) { 248 // If the path is starting with more than one "/" and no authority is present, the 249 // starting slashes MUST be reduced to one. 250 $path = '/' . \ltrim($path, '/'); 251 } 252 } 253 254 $uri .= $path; 255 } 256 257 if ('' !== $query) { 258 $uri .= '?' . $query; 259 } 260 261 if ('' !== $fragment) { 262 $uri .= '#' . $fragment; 263 } 264 265 return $uri; 266 } 267 268 /** 269 * Is a given port non-standard for the current scheme? 270 */ 271 private static function isNonStandardPort(string $scheme, int $port): bool 272 { 273 return !isset(self::SCHEMES[$scheme]) || $port !== self::SCHEMES[$scheme]; 274 } 275 276 private function filterPort($port): ?int 277 { 278 if (null === $port) { 279 return null; 280 } 281 282 $port = (int) $port; 283 if (0 > $port || 0xffff < $port) { 284 throw new \InvalidArgumentException(\sprintf('Invalid port: %d. Must be between 0 and 65535', $port)); 285 } 286 287 return self::isNonStandardPort($this->scheme, $port) ? $port : null; 288 } 289 290 private function filterPath($path): string 291 { 292 if (!\is_string($path)) { 293 throw new \InvalidArgumentException('Path must be a string'); 294 } 295 296 return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawurlencodeMatchZero'], $path); 297 } 298 299 private function filterQueryAndFragment($str): string 300 { 301 if (!\is_string($str)) { 302 throw new \InvalidArgumentException('Query and fragment must be a string'); 303 } 304 305 return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawurlencodeMatchZero'], $str); 306 } 307 308 private static function rawurlencodeMatchZero(array $match): string 309 { 310 return \rawurlencode($match[0]); 311 } 312 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |