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