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