Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Url.php
001 <?php
002 namespace GuzzleHttp;
003
004 use GuzzleHttp\Ring\Core;
005
006 /**
007 * Parses and generates URLs based on URL parts
008 */
009 class Url
010 {
011 private $scheme;
012 private $host;
013 private $port;
014 private $username;
015 private $password;
016 private $path = '';
017 private $fragment;
018 private static $defaultPorts = ['http' => 80, 'https' => 443, 'ftp' => 21];
019 private static $pathPattern = '/[^a-zA-Z0-9\-\._~!\$&\'\(\)\*\+,;=%:@\/]+|%(?![A-Fa-f0-9]{2})/';
020 private static $queryPattern = '/[^a-zA-Z0-9\-\._~!\$\'\(\)\*\+,;%:@\/\?=&]+|%(?![A-Fa-f0-9]{2})/';
021 /** @var Query|string Query part of the URL */
022 private $query;
023
024 /**
025 * Factory method to create a new URL from a URL string
026 *
027 * @param string $url Full URL used to create a Url object
028 *
029 * @return Url
030 * @throws \InvalidArgumentException
031 */
032 public static function fromString($url)
033 {
034 static $defaults = ['scheme' => null, 'host' => null,
035 'path' => null, 'port' => null, 'query' => null,
036 'user' => null, 'pass' => null, 'fragment' => null];
037
038 if (false === ($parts = parse_url($url))) {
039 throw new \InvalidArgumentException('Unable to parse malformed '
040 . 'url: ' . $url);
041 }
042
043 $parts += $defaults;
044
045 // Convert the query string into a Query object
046 if ($parts['query'] || 0 !== strlen($parts['query'])) {
047 $parts['query'] = Query::fromString($parts['query']);
048 }
049
050 return new static($parts['scheme'], $parts['host'], $parts['user'],
051 $parts['pass'], $parts['port'], $parts['path'], $parts['query'],
052 $parts['fragment']);
053 }
054
055 /**
056 * Build a URL from parse_url parts. The generated URL will be a relative
057 * URL if a scheme or host are not provided.
058 *
059 * @param array $parts Array of parse_url parts
060 *
061 * @return string
062 */
063 public static function buildUrl(array $parts)
064 {
065 $url = $scheme = '';
066
067 if (!empty($parts['scheme'])) {
068 $scheme = $parts['scheme'];
069 $url .= $scheme . ':';
070 }
071
072 if (!empty($parts['host'])) {
073 $url .= '//';
074 if (isset($parts['user'])) {
075 $url .= $parts['user'];
076 if (isset($parts['pass'])) {
077 $url .= ':' . $parts['pass'];
078 }
079 $url .= '@';
080 }
081
082 $url .= $parts['host'];
083
084 // Only include the port if it is not the default port of the scheme
085 if (isset($parts['port']) &&
086 (!isset(self::$defaultPorts[$scheme]) ||
087 $parts['port'] != self::$defaultPorts[$scheme])
088 ) {
089 $url .= ':' . $parts['port'];
090 }
091 }
092
093 // Add the path component if present
094 if (isset($parts['path']) && strlen($parts['path'])) {
095 // Always ensure that the path begins with '/' if set and something
096 // is before the path
097 if (!empty($parts['host']) && $parts['path'][0] != '/') {
098 $url .= '/';
099 }
100 $url .= $parts['path'];
101 }
102
103 // Add the query string if present
104 if (isset($parts['query'])) {
105 $queryStr = (string) $parts['query'];
106 if ($queryStr || $queryStr === '0') {
107 $url .= '?' . $queryStr;
108 }
109 }
110
111 // Ensure that # is only added to the url if fragment contains anything.
112 if (isset($parts['fragment'])) {
113 $url .= '#' . $parts['fragment'];
114 }
115
116 return $url;
117 }
118
119 /**
120 * Create a new URL from URL parts
121 *
122 * @param string $scheme Scheme of the URL
123 * @param string $host Host of the URL
124 * @param string $username Username of the URL
125 * @param string $password Password of the URL
126 * @param int $port Port of the URL
127 * @param string $path Path of the URL
128 * @param Query|array|string $query Query string of the URL
129 * @param string $fragment Fragment of the URL
130 */
131 public function __construct(
132 $scheme,
133 $host,
134 $username = null,
135 $password = null,
136 $port = null,
137 $path = null,
138 $query = null,
139 $fragment = null
140 ) {
141 $this->scheme = strtolower($scheme);
142 $this->host = $host;
143 $this->port = $port;
144 $this->username = $username;
145 $this->password = $password;
146 $this->fragment = $fragment;
147
148 if ($query) {
149 $this->setQuery($query);
150 }
151
152 $this->setPath($path);
153 }
154
155 /**
156 * Clone the URL
157 */
158 public function __clone()
159 {
160 if ($this->query instanceof Query) {
161 $this->query = clone $this->query;
162 }
163 }
164
165 /**
166 * Returns the URL as a URL string
167 *
168 * @return string
169 */
170 public function __toString()
171 {
172 return static::buildUrl($this->getParts());
173 }
174
175 /**
176 * Get the parts of the URL as an array
177 *
178 * @return array
179 */
180 public function getParts()
181 {
182 return array(
183 'scheme' => $this->scheme,
184 'user' => $this->username,
185 'pass' => $this->password,
186 'host' => $this->host,
187 'port' => $this->port,
188 'path' => $this->path,
189 'query' => $this->query,
190 'fragment' => $this->fragment,
191 );
192 }
193
194 /**
195 * Set the host of the request.
196 *
197 * @param string $host Host to set (e.g. www.yahoo.com, yahoo.com)
198 *
199 * @return Url
200 */
201 public function setHost($host)
202 {
203 if (strpos($host, ':') === false) {
204 $this->host = $host;
205 } else {
206 list($host, $port) = explode(':', $host);
207 $this->host = $host;
208 $this->setPort($port);
209 }
210 }
211
212 /**
213 * Get the host part of the URL
214 *
215 * @return string
216 */
217 public function getHost()
218 {
219 return $this->host;
220 }
221
222 /**
223 * Set the scheme part of the URL (http, https, ftp, etc.)
224 *
225 * @param string $scheme Scheme to set
226 */
227 public function setScheme($scheme)
228 {
229 // Remove the default port if one is specified
230 if ($this->port
231 && isset(self::$defaultPorts[$this->scheme])
232 && self::$defaultPorts[$this->scheme] == $this->port
233 ) {
234 $this->port = null;
235 }
236
237 $this->scheme = strtolower($scheme);
238 }
239
240 /**
241 * Get the scheme part of the URL
242 *
243 * @return string
244 */
245 public function getScheme()
246 {
247 return $this->scheme;
248 }
249
250 /**
251 * Set the port part of the URL
252 *
253 * @param int $port Port to set
254 */
255 public function setPort($port)
256 {
257 $this->port = $port;
258 }
259
260 /**
261 * Get the port part of the URl.
262 *
263 * If no port was set, this method will return the default port for the
264 * scheme of the URI.
265 *
266 * @return int|null
267 */
268 public function getPort()
269 {
270 if ($this->port) {
271 return $this->port;
272 } elseif (isset(self::$defaultPorts[$this->scheme])) {
273 return self::$defaultPorts[$this->scheme];
274 }
275
276 return null;
277 }
278
279 /**
280 * Set the path part of the URL.
281 *
282 * The provided URL is URL encoded as necessary.
283 *
284 * @param string $path Path string to set
285 */
286 public function setPath($path)
287 {
288 $this->path = self::encodePath($path);
289 }
290
291 /**
292 * Removes dot segments from a URL
293 * @link http://tools.ietf.org/html/rfc3986#section-5.2.4
294 */
295 public function removeDotSegments()
296 {
297 static $noopPaths = ['' => true, '/' => true, '*' => true];
298 static $ignoreSegments = ['.' => true, '..' => true];
299
300 if (isset($noopPaths[$this->path])) {
301 return;
302 }
303
304 $results = [];
305 $segments = $this->getPathSegments();
306 foreach ($segments as $segment) {
307 if ($segment == '..') {
308 array_pop($results);
309 } elseif (!isset($ignoreSegments[$segment])) {
310 $results[] = $segment;
311 }
312 }
313
314 $newPath = implode('/', $results);
315
316 // Add the leading slash if necessary
317 if (substr($this->path, 0, 1) === '/' &&
318 substr($newPath, 0, 1) !== '/'
319 ) {
320 $newPath = '/' . $newPath;
321 }
322
323 // Add the trailing slash if necessary
324 if ($newPath != '/' && isset($ignoreSegments[end($segments)])) {
325 $newPath .= '/';
326 }
327
328 $this->path = $newPath;
329 }
330
331 /**
332 * Add a relative path to the currently set path.
333 *
334 * @param string $relativePath Relative path to add
335 */
336 public function addPath($relativePath)
337 {
338 if ($relativePath != '/' &&
339 is_string($relativePath) &&
340 strlen($relativePath) > 0
341 ) {
342 // Add a leading slash if needed
343 if ($relativePath[0] !== '/' &&
344 substr($this->path, -1, 1) !== '/'
345 ) {
346 $relativePath = '/' . $relativePath;
347 }
348
349 $this->setPath($this->path . $relativePath);
350 }
351 }
352
353 /**
354 * Get the path part of the URL
355 *
356 * @return string
357 */
358 public function getPath()
359 {
360 return $this->path;
361 }
362
363 /**
364 * Get the path segments of the URL as an array
365 *
366 * @return array
367 */
368 public function getPathSegments()
369 {
370 return explode('/', $this->path);
371 }
372
373 /**
374 * Set the password part of the URL
375 *
376 * @param string $password Password to set
377 */
378 public function setPassword($password)
379 {
380 $this->password = $password;
381 }
382
383 /**
384 * Get the password part of the URL
385 *
386 * @return null|string
387 */
388 public function getPassword()
389 {
390 return $this->password;
391 }
392
393 /**
394 * Set the username part of the URL
395 *
396 * @param string $username Username to set
397 */
398 public function setUsername($username)
399 {
400 $this->username = $username;
401 }
402
403 /**
404 * Get the username part of the URl
405 *
406 * @return null|string
407 */
408 public function getUsername()
409 {
410 return $this->username;
411 }
412
413 /**
414 * Get the query part of the URL as a Query object
415 *
416 * @return Query
417 */
418 public function getQuery()
419 {
420 // Convert the query string to a query object if not already done.
421 if (!$this->query instanceof Query) {
422 $this->query = $this->query === null
423 ? new Query()
424 : Query::fromString($this->query);
425 }
426
427 return $this->query;
428 }
429
430 /**
431 * Set the query part of the URL.
432 *
433 * You may provide a query string as a string and pass $rawString as true
434 * to provide a query string that is not parsed until a call to getQuery()
435 * is made. Setting a raw query string will still encode invalid characters
436 * in a query string.
437 *
438 * @param Query|string|array $query Query string value to set. Can
439 * be a string that will be parsed into a Query object, an array
440 * of key value pairs, or a Query object.
441 * @param bool $rawString Set to true when providing a raw query string.
442 *
443 * @throws \InvalidArgumentException
444 */
445 public function setQuery($query, $rawString = false)
446 {
447 if ($query instanceof Query) {
448 $this->query = $query;
449 } elseif (is_string($query)) {
450 if (!$rawString) {
451 $this->query = Query::fromString($query);
452 } else {
453 // Ensure the query does not have illegal characters.
454 $this->query = preg_replace_callback(
455 self::$queryPattern,
456 [__CLASS__, 'encodeMatch'],
457 $query
458 );
459 }
460
461 } elseif (is_array($query)) {
462 $this->query = new Query($query);
463 } else {
464 throw new \InvalidArgumentException('Query must be a Query, '
465 . 'array, or string. Got ' . Core::describeType($query));
466 }
467 }
468
469 /**
470 * Get the fragment part of the URL
471 *
472 * @return null|string
473 */
474 public function getFragment()
475 {
476 return $this->fragment;
477 }
478
479 /**
480 * Set the fragment part of the URL
481 *
482 * @param string $fragment Fragment to set
483 */
484 public function setFragment($fragment)
485 {
486 $this->fragment = $fragment;
487 }
488
489 /**
490 * Check if this is an absolute URL
491 *
492 * @return bool
493 */
494 public function isAbsolute()
495 {
496 return $this->scheme && $this->host;
497 }
498
499 /**
500 * Combine the URL with another URL and return a new URL instance.
501 *
502 * Follows the rules specific in RFC 3986 section 5.4.
503 *
504 * @param string $url Relative URL to combine with
505 *
506 * @return Url
507 * @throws \InvalidArgumentException
508 * @link http://tools.ietf.org/html/rfc3986#section-5.4
509 */
510 public function combine($url)
511 {
512 $url = static::fromString($url);
513
514 // Use the more absolute URL as the base URL
515 if (!$this->isAbsolute() && $url->isAbsolute()) {
516 $url = $url->combine($this);
517 }
518
519 $parts = $url->getParts();
520
521 // Passing a URL with a scheme overrides everything
522 if ($parts['scheme']) {
523 return clone $url;
524 }
525
526 // Setting a host overrides the entire rest of the URL
527 if ($parts['host']) {
528 return new static(
529 $this->scheme,
530 $parts['host'],
531 $parts['user'],
532 $parts['pass'],
533 $parts['port'],
534 $parts['path'],
535 $parts['query'] instanceof Query
536 ? clone $parts['query']
537 : $parts['query'],
538 $parts['fragment']
539 );
540 }
541
542 if (!$parts['path'] && $parts['path'] !== '0') {
543 // The relative URL has no path, so check if it is just a query
544 $path = $this->path ?: '';
545 $query = $parts['query'] ?: $this->query;
546 } else {
547 $query = $parts['query'];
548 if ($parts['path'][0] == '/' || !$this->path) {
549 // Overwrite the existing path if the rel path starts with "/"
550 $path = $parts['path'];
551 } else {
552 // If the relative URL does not have a path or the base URL
553 // path does not end in a "/" then overwrite the existing path
554 // up to the last "/"
555 $path = substr($this->path, 0, strrpos($this->path, '/') + 1) . $parts['path'];
556 }
557 }
558
559 $result = new self(
560 $this->scheme,
561 $this->host,
562 $this->username,
563 $this->password,
564 $this->port,
565 $path,
566 $query instanceof Query ? clone $query : $query,
567 $parts['fragment']
568 );
569
570 if ($path) {
571 $result->removeDotSegments();
572 }
573
574 return $result;
575 }
576
577 /**
578 * Encodes the path part of a URL without double-encoding percent-encoded
579 * key value pairs.
580 *
581 * @param string $path Path to encode
582 *
583 * @return string
584 */
585 public static function encodePath($path)
586 {
587 static $cb = [__CLASS__, 'encodeMatch'];
588 return preg_replace_callback(self::$pathPattern, $cb, $path);
589 }
590
591 private static function encodeMatch(array $match)
592 {
593 return rawurlencode($match[0]);
594 }
595 }
596