Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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

Utils.php

Zuletzt modifiziert: 01.05.2026, 11:26 - Dateigröße: 14.33 KiB


 001  <?php
 002   
 003  namespace GuzzleHttp\Psr7;
 004   
 005  use Psr\Http\Message\RequestInterface;
 006  use Psr\Http\Message\ServerRequestInterface;
 007  use Psr\Http\Message\StreamInterface;
 008  use Psr\Http\Message\UriInterface;
 009   
 010  final class Utils
 011  {
 012      /**
 013       * Remove the items given by the keys, case insensitively from the data.
 014       *
 015       * @param iterable<string> $keys
 016       *
 017       * @return array
 018       */
 019      public static function caselessRemove($keys, array $data)
 020      {
 021          $result = [];
 022   
 023          foreach ($keys as &$key) {
 024              $key = strtolower($key);
 025          }
 026   
 027          foreach ($data as $k => $v) {
 028              if (!in_array(strtolower($k), $keys)) {
 029                  $result[$k] = $v;
 030              }
 031          }
 032   
 033          return $result;
 034      }
 035   
 036      /**
 037       * Copy the contents of a stream into another stream until the given number
 038       * of bytes have been read.
 039       *
 040       * @param StreamInterface $source Stream to read from
 041       * @param StreamInterface $dest   Stream to write to
 042       * @param int             $maxLen Maximum number of bytes to read. Pass -1
 043       *                                to read the entire stream.
 044       *
 045       * @throws \RuntimeException on error.
 046       */
 047      public static function copyToStream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)
 048      {
 049          $bufferSize = 8192;
 050   
 051          if ($maxLen === -1) {
 052              while (!$source->eof()) {
 053                  if (!$dest->write($source->read($bufferSize))) {
 054                      break;
 055                  }
 056              }
 057          } else {
 058              $remaining = $maxLen;
 059              while ($remaining > 0 && !$source->eof()) {
 060                  $buf = $source->read(min($bufferSize, $remaining));
 061                  $len = strlen($buf);
 062                  if (!$len) {
 063                      break;
 064                  }
 065                  $remaining -= $len;
 066                  $dest->write($buf);
 067              }
 068          }
 069      }
 070   
 071      /**
 072       * Copy the contents of a stream into a string until the given number of
 073       * bytes have been read.
 074       *
 075       * @param StreamInterface $stream Stream to read
 076       * @param int             $maxLen Maximum number of bytes to read. Pass -1
 077       *                                to read the entire stream.
 078       *
 079       * @return string
 080       *
 081       * @throws \RuntimeException on error.
 082       */
 083      public static function copyToString(StreamInterface $stream, $maxLen = -1)
 084      {
 085          $buffer = '';
 086   
 087          if ($maxLen === -1) {
 088              while (!$stream->eof()) {
 089                  $buf = $stream->read(1048576);
 090                  // Using a loose equality here to match on '' and false.
 091                  if ($buf == null) {
 092                      break;
 093                  }
 094                  $buffer .= $buf;
 095              }
 096              return $buffer;
 097          }
 098   
 099          $len = 0;
 100          while (!$stream->eof() && $len < $maxLen) {
 101              $buf = $stream->read($maxLen - $len);
 102              // Using a loose equality here to match on '' and false.
 103              if ($buf == null) {
 104                  break;
 105              }
 106              $buffer .= $buf;
 107              $len = strlen($buffer);
 108          }
 109   
 110          return $buffer;
 111      }
 112   
 113      /**
 114       * Calculate a hash of a stream.
 115       *
 116       * This method reads the entire stream to calculate a rolling hash, based
 117       * on PHP's `hash_init` functions.
 118       *
 119       * @param StreamInterface $stream    Stream to calculate the hash for
 120       * @param string          $algo      Hash algorithm (e.g. md5, crc32, etc)
 121       * @param bool            $rawOutput Whether or not to use raw output
 122       *
 123       * @return string Returns the hash of the stream
 124       *
 125       * @throws \RuntimeException on error.
 126       */
 127      public static function hash(StreamInterface $stream, $algo, $rawOutput = false)
 128      {
 129          $pos = $stream->tell();
 130   
 131          if ($pos > 0) {
 132              $stream->rewind();
 133          }
 134   
 135          $ctx = hash_init($algo);
 136          while (!$stream->eof()) {
 137              hash_update($ctx, $stream->read(1048576));
 138          }
 139   
 140          $out = hash_final($ctx, (bool) $rawOutput);
 141          $stream->seek($pos);
 142   
 143          return $out;
 144      }
 145   
 146      /**
 147       * Clone and modify a request with the given changes.
 148       *
 149       * This method is useful for reducing the number of clones needed to mutate
 150       * a message.
 151       *
 152       * The changes can be one of:
 153       * - method: (string) Changes the HTTP method.
 154       * - set_headers: (array) Sets the given headers.
 155       * - remove_headers: (array) Remove the given headers.
 156       * - body: (mixed) Sets the given body.
 157       * - uri: (UriInterface) Set the URI.
 158       * - query: (string) Set the query string value of the URI.
 159       * - version: (string) Set the protocol version.
 160       *
 161       * @param RequestInterface $request Request to clone and modify.
 162       * @param array            $changes Changes to apply.
 163       *
 164       * @return RequestInterface
 165       */
 166      public static function modifyRequest(RequestInterface $request, array $changes)
 167      {
 168          if (!$changes) {
 169              return $request;
 170          }
 171   
 172          $headers = $request->getHeaders();
 173   
 174          if (!isset($changes['uri'])) {
 175              $uri = $request->getUri();
 176          } else {
 177              // Remove the host header if one is on the URI
 178              if ($host = $changes['uri']->getHost()) {
 179                  $changes['set_headers']['Host'] = $host;
 180   
 181                  if ($port = $changes['uri']->getPort()) {
 182                      $standardPorts = ['http' => 80, 'https' => 443];
 183                      $scheme = $changes['uri']->getScheme();
 184                      if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
 185                          $changes['set_headers']['Host'] .= ':' . $port;
 186                      }
 187                  }
 188              }
 189              $uri = $changes['uri'];
 190          }
 191   
 192          if (!empty($changes['remove_headers'])) {
 193              $headers = self::caselessRemove($changes['remove_headers'], $headers);
 194          }
 195   
 196          if (!empty($changes['set_headers'])) {
 197              $headers = self::caselessRemove(array_keys($changes['set_headers']), $headers);
 198              $headers = $changes['set_headers'] + $headers;
 199          }
 200   
 201          if (isset($changes['query'])) {
 202              $uri = $uri->withQuery($changes['query']);
 203          }
 204   
 205          if ($request instanceof ServerRequestInterface) {
 206              $new = (new ServerRequest(
 207                  isset($changes['method']) ? $changes['method'] : $request->getMethod(),
 208                  $uri,
 209                  $headers,
 210                  isset($changes['body']) ? $changes['body'] : $request->getBody(),
 211                  isset($changes['version'])
 212                      ? $changes['version']
 213                      : $request->getProtocolVersion(),
 214                  $request->getServerParams()
 215              ))
 216              ->withParsedBody($request->getParsedBody())
 217              ->withQueryParams($request->getQueryParams())
 218              ->withCookieParams($request->getCookieParams())
 219              ->withUploadedFiles($request->getUploadedFiles());
 220   
 221              foreach ($request->getAttributes() as $key => $value) {
 222                  $new = $new->withAttribute($key, $value);
 223              }
 224   
 225              return $new;
 226          }
 227   
 228          return new Request(
 229              isset($changes['method']) ? $changes['method'] : $request->getMethod(),
 230              $uri,
 231              $headers,
 232              isset($changes['body']) ? $changes['body'] : $request->getBody(),
 233              isset($changes['version'])
 234                  ? $changes['version']
 235                  : $request->getProtocolVersion()
 236          );
 237      }
 238   
 239      /**
 240       * Read a line from the stream up to the maximum allowed buffer length.
 241       *
 242       * @param StreamInterface $stream    Stream to read from
 243       * @param int|null        $maxLength Maximum buffer length
 244       *
 245       * @return string
 246       */
 247      public static function readLine(StreamInterface $stream, $maxLength = null)
 248      {
 249          $buffer = '';
 250          $size = 0;
 251   
 252          while (!$stream->eof()) {
 253              // Using a loose equality here to match on '' and false.
 254              if (null == ($byte = $stream->read(1))) {
 255                  return $buffer;
 256              }
 257              $buffer .= $byte;
 258              // Break when a new line is found or the max length - 1 is reached
 259              if ($byte === "\n" || ++$size === $maxLength - 1) {
 260                  break;
 261              }
 262          }
 263   
 264          return $buffer;
 265      }
 266   
 267      /**
 268       * Create a new stream based on the input type.
 269       *
 270       * Options is an associative array that can contain the following keys:
 271       * - metadata: Array of custom metadata.
 272       * - size: Size of the stream.
 273       *
 274       * This method accepts the following `$resource` types:
 275       * - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
 276       * - `string`: Creates a stream object that uses the given string as the contents.
 277       * - `resource`: Creates a stream object that wraps the given PHP stream resource.
 278       * - `Iterator`: If the provided value implements `Iterator`, then a read-only
 279       *   stream object will be created that wraps the given iterable. Each time the
 280       *   stream is read from, data from the iterator will fill a buffer and will be
 281       *   continuously called until the buffer is equal to the requested read size.
 282       *   Subsequent read calls will first read from the buffer and then call `next`
 283       *   on the underlying iterator until it is exhausted.
 284       * - `object` with `__toString()`: If the object has the `__toString()` method,
 285       *   the object will be cast to a string and then a stream will be returned that
 286       *   uses the string value.
 287       * - `NULL`: When `null` is passed, an empty stream object is returned.
 288       * - `callable` When a callable is passed, a read-only stream object will be
 289       *   created that invokes the given callable. The callable is invoked with the
 290       *   number of suggested bytes to read. The callable can return any number of
 291       *   bytes, but MUST return `false` when there is no more data to return. The
 292       *   stream object that wraps the callable will invoke the callable until the
 293       *   number of requested bytes are available. Any additional bytes will be
 294       *   buffered and used in subsequent reads.
 295       *
 296       * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data
 297       * @param array                                                                  $options  Additional options
 298       *
 299       * @return StreamInterface
 300       *
 301       * @throws \InvalidArgumentException if the $resource arg is not valid.
 302       */
 303      public static function streamFor($resource = '', array $options = [])
 304      {
 305          if (is_scalar($resource)) {
 306              $stream = self::tryFopen('php://temp', 'r+');
 307              if ($resource !== '') {
 308                  fwrite($stream, $resource);
 309                  fseek($stream, 0);
 310              }
 311              return new Stream($stream, $options);
 312          }
 313   
 314          switch (gettype($resource)) {
 315              case 'resource':
 316                  /*
 317                   * The 'php://input' is a special stream with quirks and inconsistencies.
 318                   * We avoid using that stream by reading it into php://temp
 319                   */
 320                  $metaData = \stream_get_meta_data($resource);
 321                  if (isset($metaData['uri']) && $metaData['uri'] === 'php://input') {
 322                      $stream = self::tryFopen('php://temp', 'w+');
 323                      fwrite($stream, stream_get_contents($resource));
 324                      fseek($stream, 0);
 325                      $resource = $stream;
 326                  }
 327                  return new Stream($resource, $options);
 328              case 'object':
 329                  if ($resource instanceof StreamInterface) {
 330                      return $resource;
 331                  } elseif ($resource instanceof \Iterator) {
 332                      return new PumpStream(function () use ($resource) {
 333                          if (!$resource->valid()) {
 334                              return false;
 335                          }
 336                          $result = $resource->current();
 337                          $resource->next();
 338                          return $result;
 339                      }, $options);
 340                  } elseif (method_exists($resource, '__toString')) {
 341                      return Utils::streamFor((string) $resource, $options);
 342                  }
 343                  break;
 344              case 'NULL':
 345                  return new Stream(self::tryFopen('php://temp', 'r+'), $options);
 346          }
 347   
 348          if (is_callable($resource)) {
 349              return new PumpStream($resource, $options);
 350          }
 351   
 352          throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
 353      }
 354   
 355      /**
 356       * Safely opens a PHP stream resource using a filename.
 357       *
 358       * When fopen fails, PHP normally raises a warning. This function adds an
 359       * error handler that checks for errors and throws an exception instead.
 360       *
 361       * @param string $filename File to open
 362       * @param string $mode     Mode used to open the file
 363       *
 364       * @return resource
 365       *
 366       * @throws \RuntimeException if the file cannot be opened
 367       */
 368      public static function tryFopen($filename, $mode)
 369      {
 370          $ex = null;
 371          set_error_handler(function () use ($filename, $mode, &$ex) {
 372              $ex = new \RuntimeException(sprintf(
 373                  'Unable to open "%s" using mode "%s": %s',
 374                  $filename,
 375                  $mode,
 376                  func_get_args()[1]
 377              ));
 378   
 379              return true;
 380          });
 381   
 382          try {
 383              $handle = fopen($filename, $mode);
 384          } catch (\Throwable $e) {
 385              $ex = new \RuntimeException(sprintf(
 386                  'Unable to open "%s" using mode "%s": %s',
 387                  $filename,
 388                  $mode,
 389                  $e->getMessage()
 390              ), 0, $e);
 391          }
 392   
 393          restore_error_handler();
 394   
 395          if ($ex) {
 396              /** @var $ex \RuntimeException */
 397              throw $ex;
 398          }
 399   
 400          return $handle;
 401      }
 402   
 403      /**
 404       * Returns a UriInterface for the given value.
 405       *
 406       * This function accepts a string or UriInterface and returns a
 407       * UriInterface for the given value. If the value is already a
 408       * UriInterface, it is returned as-is.
 409       *
 410       * @param string|UriInterface $uri
 411       *
 412       * @return UriInterface
 413       *
 414       * @throws \InvalidArgumentException
 415       */
 416      public static function uriFor($uri)
 417      {
 418          if ($uri instanceof UriInterface) {
 419              return $uri;
 420          }
 421   
 422          if (is_string($uri)) {
 423              return new Uri($uri);
 424          }
 425   
 426          throw new \InvalidArgumentException('URI must be a string or UriInterface');
 427      }
 428  }
 429