[ Index ]

PHP Cross Reference of phpBB-3.3.9-deutsch

title

Body

[close]

/vendor/guzzlehttp/psr7/src/ -> Utils.php (source)

   1  <?php
   2  
   3  namespace GuzzleHttp\Psr7;
   4  
   5  use Psr\Http\Message\RequestInterface;
   6  use Psr\Http\Message\ServerRequestInterface;
   7  use Psr\Http\Message\StreamInterface;
   8  use Psr\Http\Message\UriInterface;
   9  
  10  final class Utils
  11  {
  12      /**
  13       * Remove the items given by the keys, case insensitively from the data.
  14       *
  15       * @param iterable<string> $keys
  16       *
  17       * @return array
  18       */
  19      public static function caselessRemove($keys, array $data)
  20      {
  21          $result = [];
  22  
  23          foreach ($keys as &$key) {
  24              $key = strtolower($key);
  25          }
  26  
  27          foreach ($data as $k => $v) {
  28              if (!in_array(strtolower($k), $keys)) {
  29                  $result[$k] = $v;
  30              }
  31          }
  32  
  33          return $result;
  34      }
  35  
  36      /**
  37       * Copy the contents of a stream into another stream until the given number
  38       * of bytes have been read.
  39       *
  40       * @param StreamInterface $source Stream to read from
  41       * @param StreamInterface $dest   Stream to write to
  42       * @param int             $maxLen Maximum number of bytes to read. Pass -1
  43       *                                to read the entire stream.
  44       *
  45       * @throws \RuntimeException on error.
  46       */
  47      public static function copyToStream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)
  48      {
  49          $bufferSize = 8192;
  50  
  51          if ($maxLen === -1) {
  52              while (!$source->eof()) {
  53                  if (!$dest->write($source->read($bufferSize))) {
  54                      break;
  55                  }
  56              }
  57          } else {
  58              $remaining = $maxLen;
  59              while ($remaining > 0 && !$source->eof()) {
  60                  $buf = $source->read(min($bufferSize, $remaining));
  61                  $len = strlen($buf);
  62                  if (!$len) {
  63                      break;
  64                  }
  65                  $remaining -= $len;
  66                  $dest->write($buf);
  67              }
  68          }
  69      }
  70  
  71      /**
  72       * Copy the contents of a stream into a string until the given number of
  73       * bytes have been read.
  74       *
  75       * @param StreamInterface $stream Stream to read
  76       * @param int             $maxLen Maximum number of bytes to read. Pass -1
  77       *                                to read the entire stream.
  78       *
  79       * @return string
  80       *
  81       * @throws \RuntimeException on error.
  82       */
  83      public static function copyToString(StreamInterface $stream, $maxLen = -1)
  84      {
  85          $buffer = '';
  86  
  87          if ($maxLen === -1) {
  88              while (!$stream->eof()) {
  89                  $buf = $stream->read(1048576);
  90                  // Using a loose equality here to match on '' and false.
  91                  if ($buf == null) {
  92                      break;
  93                  }
  94                  $buffer .= $buf;
  95              }
  96              return $buffer;
  97          }
  98  
  99          $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  }


Generated: Wed Dec 7 15:09:22 2022 Cross-referenced by PHPXref 0.7.1