Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
uri.php
1<?php
2
10namespace Bitrix\Main\Web;
11
12use Bitrix\Main;
14use Psr\Http\Message\UriInterface;
15
16class Uri implements \JsonSerializable, UriInterface
17{
18 protected $scheme = '';
19 protected $host = '';
20 protected $port = null;
21 protected $user = '';
22 protected $pass = '';
23 protected $path = '';
24 protected $query = '';
25 protected $fragment = '';
26
30 public function __construct($url)
31 {
32 if (str_starts_with($url, '/'))
33 {
34 //we don't support "current scheme" e.g. "//host/path"
35 $url = '/' . ltrim($url, '/');
36 }
37
38 $parsedUrl = parse_url($url);
39
40 if ($parsedUrl !== false)
41 {
42 $this->scheme = strtolower($parsedUrl['scheme'] ?? '');
43 $this->host = strtolower($parsedUrl['host'] ?? '');
44 $this->port = $parsedUrl['port'] ?? null;
45 $this->user = $parsedUrl['user'] ?? '';
46 $this->pass = $parsedUrl['pass'] ?? '';
47 $this->path = $parsedUrl['path'] ?? '';
48 $this->query = $parsedUrl['query'] ?? '';
49 $this->fragment = $parsedUrl['fragment'] ?? '';
50 }
51 }
52
56 public function getUrl()
57 {
58 return $this->getLocator();
59 }
60
65 public function getLocator()
66 {
67 $uri = '';
68
69 $scheme = $this->getScheme();
70 if ($scheme != '')
71 {
72 $uri .= $scheme . ':';
73 }
74
75 $authority = $this->getAuthority();
76 if ($authority != '')
77 {
78 $uri .= '//' . $authority;
79 }
80
81 $uri .= $this->getPathQuery();
82
83 return $uri;
84 }
85
90 public function getUri()
91 {
92 $url = $this->getLocator();
93 $fragment = $this->getFragment();
94
95 if ($fragment != '')
96 {
97 $url .= '#' . $fragment;
98 }
99
100 return $url;
101 }
102
106 public function getFragment(): string
107 {
108 return $this->fragment;
109 }
110
114 public function getHost(): string
115 {
116 return $this->host;
117 }
118
124 public function setHost($host)
125 {
126 $this->host = strtolower($host);
127 return $this;
128 }
129
134 public function getPass()
135 {
136 return $this->pass;
137 }
138
144 public function setPass($pass)
145 {
146 $this->pass = $pass;
147 return $this;
148 }
149
153 public function getPath(): string
154 {
155 // TODO: make it work as described
156 return $this->path;
157 }
158
164 public function setPath($path)
165 {
166 $this->path = $path;
167 return $this;
168 }
169
174 public function getPathQuery()
175 {
176 $pathQuery = $this->getPath();
177
178 if ($pathQuery == '')
179 {
180 $pathQuery = '/';
181 }
182
183 $query = $this->getQuery();
184
185 if ($query != '')
186 {
187 $pathQuery .= '?' . $query;
188 }
189
190 return $pathQuery;
191 }
192
196 public function getPort(): ?int
197 {
198 if ($this->port === null)
199 {
200 switch ($this->getScheme())
201 {
202 case 'https':
203 return 443;
204 case 'http':
205 return 80;
206 default:
207 return null;
208 }
209 }
210 return (int)$this->port;
211 }
212
216 public function getQuery(): string
217 {
218 return $this->query;
219 }
220
224 public function getScheme(): string
225 {
226 return $this->scheme;
227 }
228
233 public function getUser()
234 {
235 return $this->user;
236 }
237
243 public function setUser($user)
244 {
245 $this->user = $user;
246 return $this;
247 }
248
254 protected static function parseParams($params)
255 {
256 $data = preg_replace_callback(
257 '/(?:^|(?<=&))[^=[]+/',
258 function($match)
259 {
260 return bin2hex(urldecode($match[0]));
261 },
262 $params
263 );
264
265 parse_str($data, $values);
266
267 return array_combine(array_map('hex2bin', array_keys($values)), $values);
268 }
269
276 public function deleteParams(array $params, $preserveDots = false)
277 {
278 $query = $this->getQuery();
279 if ($query != '')
280 {
281 if ($preserveDots)
282 {
283 $currentParams = static::parseParams($query);
284 }
285 else
286 {
287 $currentParams = [];
289 }
290
291 foreach($params as $param)
292 {
293 unset($currentParams[$param]);
294 }
295
296 $this->query = http_build_query($currentParams, '', '&', PHP_QUERY_RFC3986);
297 }
298 return $this;
299 }
300
307 public function addParams(array $params, $preserveDots = false)
308 {
309 $currentParams = [];
310 $query = $this->getQuery();
311
312 if ($query != '')
313 {
314 if ($preserveDots)
315 {
316 $currentParams = static::parseParams($query);
317 }
318 else
319 {
321 }
322 }
323
325
326 $this->query = http_build_query($currentParams, '', '&', PHP_QUERY_RFC3986);
327
328 return $this;
329 }
330
334 public function __toString(): string
335 {
336 return $this->getUri();
337 }
338
346 public function jsonSerialize(): string
347 {
348 return $this->getUri();
349 }
350
355 public function convertToPunycode()
356 {
357 $host = \CBXPunycode::ToASCII($this->getHost(), $encodingErrors);
358
360 {
361 return new \Bitrix\Main\Error(implode("\n", $encodingErrors));
362 }
363
364 $this->setHost($host);
365
366 return $host;
367 }
368
372 public function isPathTraversal(): bool
373 {
374 return (bool)preg_match("#(?:/|2f|^|\\\\|5c)(?:(?:%0*(25)*2e)|\\.){2,}(?:/|%0*(25)*2f|\\\\|%0*(25)*5c|$)#i", $this->getPath());
375 }
376
383 public static function urnEncode($str, $charset = 'UTF-8')
384 {
385 $result = '';
386 $arParts = preg_split("#(://|:\\d+/|/|\\?|=|&)#", $str, -1, PREG_SPLIT_DELIM_CAPTURE);
387
388 if ($charset === false)
389 {
390 foreach ($arParts as $i => $part)
391 {
392 $result .= ($i % 2) ? $part : rawurlencode($part);
393 }
394 }
395 else
396 {
397 $currentCharset = Main\Context::getCurrent()->getCulture()->getCharset();
398 foreach ($arParts as $i => $part)
399 {
400 $result .= ($i % 2) ? $part : rawurlencode(Encoding::convertEncoding($part, $currentCharset, $charset));
401 }
402 }
403 return $result;
404 }
405
412 public static function urnDecode($str, $charset = false)
413 {
414 $result = '';
415 $arParts = preg_split("#(://|:\\d+/|/|\\?|=|&)#", $str, -1, PREG_SPLIT_DELIM_CAPTURE);
416
417 if ($charset === false)
418 {
419 foreach ($arParts as $i => $part)
420 {
421 $result .= ($i % 2) ? $part : rawurldecode($part);
422 }
423 }
424 else
425 {
426 $currentCharset = Main\Context::getCurrent()->getCulture()->getCharset();
427 foreach ($arParts as $i => $part)
428 {
429 $result .= ($i % 2) ? $part : rawurldecode(Encoding::convertEncoding($part, $charset, $currentCharset));
430 }
431 }
432 return $result;
433 }
434
440 public function toAbsolute(string $host = null): Uri
441 {
442 if ($this->host == '')
443 {
444 $request = Main\HttpContext::getCurrent()->getRequest();
445
446 $this->scheme = $request->isHttps() ? 'https' : 'http';
447
448 if ($host !== null)
449 {
450 $this->host = preg_replace('/:(443|80)$/', '', $host);
451 }
452 else
453 {
454 $this->host = $request->getHttpHost();
455 }
456 }
457 return $this;
458 }
459
463 public function getAuthority(): string
464 {
465 $authority = '';
466
467 $userInfo = $this->getUserInfo();
468 if ($userInfo != '')
469 {
470 $authority = $userInfo . '@';
471 }
472
473 $host = $this->getHost();
474 if ($host != '')
475 {
476 $authority .= $host;
477 $port = $this->getPort();
478
479 if ($port !== null)
480 {
481 if (($this->scheme == 'http' && $port != 80) || ($this->scheme == 'https' && $port != 443))
482 {
483 $authority .= ':' . $port;
484 }
485 }
486 }
487
488 return $authority;
489 }
490
494 public function getUserInfo(): string
495 {
496 $user = $this->getUser();
497
498 if ($user != '')
499 {
500 $password = $this->getPass();
501 return $user . ($password != '' ? ':' . $password : '');
502 }
503
504 return '';
505 }
506
510 public function withScheme(string $scheme): UriInterface
511 {
512 $new = clone $this;
513 $new->scheme = $scheme;
514
515 return $new;
516 }
517
521 public function withUserInfo(string $user, ?string $password = null): UriInterface
522 {
523 $new = clone $this;
524 $new
525 ->setUser($user)
526 ->setPass((string)$password)
527 ;
528
529 return $new;
530 }
531
535 public function withHost(string $host): UriInterface
536 {
537 $new = clone $this;
538 $new->setHost($host);
539
540 return $new;
541 }
542
546 public function withPort(?int $port): UriInterface
547 {
548 $new = clone $this;
549 $new->port = $port;
550
551 return $new;
552 }
553
557 public function withPath(string $path): UriInterface
558 {
559 $new = clone $this;
560 $new->setPath($path);
561
562 return $new;
563 }
564
568 public function withQuery(string $query): UriInterface
569 {
570 $new = clone $this;
571 $new->query = $query;
572
573 return $new;
574 }
575
579 public function withFragment(string $fragment): UriInterface
580 {
581 $new = clone $this;
582 $new->fragment = $fragment;
583
584 return $new;
585 }
586}
withFragment(string $fragment)
Definition uri.php:579
withUserInfo(string $user, ?string $password=null)
Definition uri.php:521
static urnDecode($str, $charset=false)
Definition uri.php:412
toAbsolute(string $host=null)
Definition uri.php:440
withScheme(string $scheme)
Definition uri.php:510
withQuery(string $query)
Definition uri.php:568
static parseParams($params)
Definition uri.php:254
deleteParams(array $params, $preserveDots=false)
Definition uri.php:276
withHost(string $host)
Definition uri.php:535
addParams(array $params, $preserveDots=false)
Definition uri.php:307
withPath(string $path)
Definition uri.php:557
withPort(?int $port)
Definition uri.php:546
__construct($url)
Definition uri.php:30
static urnEncode($str, $charset='UTF-8')
Definition uri.php:383