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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Url.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 15.51 KiB


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