[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/laminas/laminas-diactoros/src/ -> MessageTrait.php (source)

   1  <?php
   2  
   3  /**
   4   * @see       https://github.com/laminas/laminas-diactoros for the canonical source repository
   5   * @copyright https://github.com/laminas/laminas-diactoros/blob/master/COPYRIGHT.md
   6   * @license   https://github.com/laminas/laminas-diactoros/blob/master/LICENSE.md New BSD License
   7   */
   8  
   9  declare(strict_types=1);
  10  
  11  namespace Laminas\Diactoros;
  12  
  13  use Psr\Http\Message\MessageInterface;
  14  use Psr\Http\Message\StreamInterface;
  15  
  16  use function array_map;
  17  use function array_merge;
  18  use function get_class;
  19  use function gettype;
  20  use function implode;
  21  use function is_array;
  22  use function is_object;
  23  use function is_resource;
  24  use function is_string;
  25  use function preg_match;
  26  use function sprintf;
  27  use function strtolower;
  28  
  29  /**
  30   * Trait implementing the various methods defined in MessageInterface.
  31   *
  32   * @see https://github.com/php-fig/http-message/tree/master/src/MessageInterface.php
  33   */
  34  trait MessageTrait
  35  {
  36      /**
  37       * List of all registered headers, as key => array of values.
  38       *
  39       * @var array
  40       */
  41      protected $headers = [];
  42  
  43      /**
  44       * Map of normalized header name to original name used to register header.
  45       *
  46       * @var array
  47       */
  48      protected $headerNames = [];
  49  
  50      /**
  51       * @var string
  52       */
  53      private $protocol = '1.1';
  54  
  55      /**
  56       * @var StreamInterface
  57       */
  58      private $stream;
  59  
  60      /**
  61       * Retrieves the HTTP protocol version as a string.
  62       *
  63       * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
  64       *
  65       * @return string HTTP protocol version.
  66       */
  67      public function getProtocolVersion() : string
  68      {
  69          return $this->protocol;
  70      }
  71  
  72      /**
  73       * Return an instance with the specified HTTP protocol version.
  74       *
  75       * The version string MUST contain only the HTTP version number (e.g.,
  76       * "1.1", "1.0").
  77       *
  78       * This method MUST be implemented in such a way as to retain the
  79       * immutability of the message, and MUST return an instance that has the
  80       * new protocol version.
  81       *
  82       * @param string $version HTTP protocol version
  83       * @return static
  84       */
  85      public function withProtocolVersion($version) : MessageInterface
  86      {
  87          $this->validateProtocolVersion($version);
  88          $new = clone $this;
  89          $new->protocol = $version;
  90          return $new;
  91      }
  92  
  93      /**
  94       * Retrieves all message headers.
  95       *
  96       * The keys represent the header name as it will be sent over the wire, and
  97       * each value is an array of strings associated with the header.
  98       *
  99       *     // Represent the headers as a string
 100       *     foreach ($message->getHeaders() as $name => $values) {
 101       *         echo $name . ": " . implode(", ", $values);
 102       *     }
 103       *
 104       *     // Emit headers iteratively:
 105       *     foreach ($message->getHeaders() as $name => $values) {
 106       *         foreach ($values as $value) {
 107       *             header(sprintf('%s: %s', $name, $value), false);
 108       *         }
 109       *     }
 110       *
 111       * @return array Returns an associative array of the message's headers. Each
 112       *     key MUST be a header name, and each value MUST be an array of strings.
 113       */
 114      public function getHeaders() : array
 115      {
 116          return $this->headers;
 117      }
 118  
 119      /**
 120       * Checks if a header exists by the given case-insensitive name.
 121       *
 122       * @param string $header Case-insensitive header name.
 123       * @return bool Returns true if any header names match the given header
 124       *     name using a case-insensitive string comparison. Returns false if
 125       *     no matching header name is found in the message.
 126       */
 127      public function hasHeader($header) : bool
 128      {
 129          return isset($this->headerNames[strtolower($header)]);
 130      }
 131  
 132      /**
 133       * Retrieves a message header value by the given case-insensitive name.
 134       *
 135       * This method returns an array of all the header values of the given
 136       * case-insensitive header name.
 137       *
 138       * If the header does not appear in the message, this method MUST return an
 139       * empty array.
 140       *
 141       * @param string $header Case-insensitive header field name.
 142       * @return string[] An array of string values as provided for the given
 143       *    header. If the header does not appear in the message, this method MUST
 144       *    return an empty array.
 145       */
 146      public function getHeader($header) : array
 147      {
 148          if (! $this->hasHeader($header)) {
 149              return [];
 150          }
 151  
 152          $header = $this->headerNames[strtolower($header)];
 153  
 154          return $this->headers[$header];
 155      }
 156  
 157      /**
 158       * Retrieves a comma-separated string of the values for a single header.
 159       *
 160       * This method returns all of the header values of the given
 161       * case-insensitive header name as a string concatenated together using
 162       * a comma.
 163       *
 164       * NOTE: Not all header values may be appropriately represented using
 165       * comma concatenation. For such headers, use getHeader() instead
 166       * and supply your own delimiter when concatenating.
 167       *
 168       * If the header does not appear in the message, this method MUST return
 169       * an empty string.
 170       *
 171       * @param string $name Case-insensitive header field name.
 172       * @return string A string of values as provided for the given header
 173       *    concatenated together using a comma. If the header does not appear in
 174       *    the message, this method MUST return an empty string.
 175       */
 176      public function getHeaderLine($name) : string
 177      {
 178          $value = $this->getHeader($name);
 179          if (empty($value)) {
 180              return '';
 181          }
 182  
 183          return implode(',', $value);
 184      }
 185  
 186      /**
 187       * Return an instance with the provided header, replacing any existing
 188       * values of any headers with the same case-insensitive name.
 189       *
 190       * While header names are case-insensitive, the casing of the header will
 191       * be preserved by this function, and returned from getHeaders().
 192       *
 193       * This method MUST be implemented in such a way as to retain the
 194       * immutability of the message, and MUST return an instance that has the
 195       * new and/or updated header and value.
 196       *
 197       * @param string $header Case-insensitive header field name.
 198       * @param string|string[] $value Header value(s).
 199       * @return static
 200       * @throws Exception\InvalidArgumentException for invalid header names or values.
 201       */
 202      public function withHeader($header, $value) : MessageInterface
 203      {
 204          $this->assertHeader($header);
 205  
 206          $normalized = strtolower($header);
 207  
 208          $new = clone $this;
 209          if ($new->hasHeader($header)) {
 210              unset($new->headers[$new->headerNames[$normalized]]);
 211          }
 212  
 213          $value = $this->filterHeaderValue($value);
 214  
 215          $new->headerNames[$normalized] = $header;
 216          $new->headers[$header]         = $value;
 217  
 218          return $new;
 219      }
 220  
 221      /**
 222       * Return an instance with the specified header appended with the
 223       * given value.
 224       *
 225       * Existing values for the specified header will be maintained. The new
 226       * value(s) will be appended to the existing list. If the header did not
 227       * exist previously, it will be added.
 228       *
 229       * This method MUST be implemented in such a way as to retain the
 230       * immutability of the message, and MUST return an instance that has the
 231       * new header and/or value.
 232       *
 233       * @param string $header Case-insensitive header field name to add.
 234       * @param string|string[] $value Header value(s).
 235       * @return static
 236       * @throws Exception\InvalidArgumentException for invalid header names or values.
 237       */
 238      public function withAddedHeader($header, $value) : MessageInterface
 239      {
 240          $this->assertHeader($header);
 241  
 242          if (! $this->hasHeader($header)) {
 243              return $this->withHeader($header, $value);
 244          }
 245  
 246          $header = $this->headerNames[strtolower($header)];
 247  
 248          $new = clone $this;
 249          $value = $this->filterHeaderValue($value);
 250          $new->headers[$header] = array_merge($this->headers[$header], $value);
 251          return $new;
 252      }
 253  
 254      /**
 255       * Return an instance without the specified header.
 256       *
 257       * Header resolution MUST be done without case-sensitivity.
 258       *
 259       * This method MUST be implemented in such a way as to retain the
 260       * immutability of the message, and MUST return an instance that removes
 261       * the named header.
 262       *
 263       * @param string $header Case-insensitive header field name to remove.
 264       * @return static
 265       */
 266      public function withoutHeader($header) : MessageInterface
 267      {
 268          if (! $this->hasHeader($header)) {
 269              return clone $this;
 270          }
 271  
 272          $normalized = strtolower($header);
 273          $original   = $this->headerNames[$normalized];
 274  
 275          $new = clone $this;
 276          unset($new->headers[$original], $new->headerNames[$normalized]);
 277          return $new;
 278      }
 279  
 280      /**
 281       * Gets the body of the message.
 282       *
 283       * @return StreamInterface Returns the body as a stream.
 284       */
 285      public function getBody() : StreamInterface
 286      {
 287          return $this->stream;
 288      }
 289  
 290      /**
 291       * Return an instance with the specified message body.
 292       *
 293       * The body MUST be a StreamInterface object.
 294       *
 295       * This method MUST be implemented in such a way as to retain the
 296       * immutability of the message, and MUST return a new instance that has the
 297       * new body stream.
 298       *
 299       * @param StreamInterface $body Body.
 300       * @return static
 301       * @throws Exception\InvalidArgumentException When the body is not valid.
 302       */
 303      public function withBody(StreamInterface $body) : MessageInterface
 304      {
 305          $new = clone $this;
 306          $new->stream = $body;
 307          return $new;
 308      }
 309  
 310      private function getStream($stream, string $modeIfNotInstance) : StreamInterface
 311      {
 312          if ($stream instanceof StreamInterface) {
 313              return $stream;
 314          }
 315  
 316          if (! is_string($stream) && ! is_resource($stream)) {
 317              throw new Exception\InvalidArgumentException(
 318                  'Stream must be a string stream resource identifier, '
 319                  . 'an actual stream resource, '
 320                  . 'or a Psr\Http\Message\StreamInterface implementation'
 321              );
 322          }
 323  
 324          return new Stream($stream, $modeIfNotInstance);
 325      }
 326  
 327      /**
 328       * Filter a set of headers to ensure they are in the correct internal format.
 329       *
 330       * Used by message constructors to allow setting all initial headers at once.
 331       *
 332       * @param array $originalHeaders Headers to filter.
 333       */
 334      private function setHeaders(array $originalHeaders) : void
 335      {
 336          $headerNames = $headers = [];
 337  
 338          foreach ($originalHeaders as $header => $value) {
 339              $value = $this->filterHeaderValue($value);
 340  
 341              $this->assertHeader($header);
 342  
 343              $headerNames[strtolower($header)] = $header;
 344              $headers[$header] = $value;
 345          }
 346  
 347          $this->headerNames = $headerNames;
 348          $this->headers = $headers;
 349      }
 350  
 351      /**
 352       * Validate the HTTP protocol version
 353       *
 354       * @param string $version
 355       * @throws Exception\InvalidArgumentException on invalid HTTP protocol version
 356       */
 357      private function validateProtocolVersion($version) : void
 358      {
 359          if (empty($version)) {
 360              throw new Exception\InvalidArgumentException(
 361                  'HTTP protocol version can not be empty'
 362              );
 363          }
 364          if (! is_string($version)) {
 365              throw new Exception\InvalidArgumentException(sprintf(
 366                  'Unsupported HTTP protocol version; must be a string, received %s',
 367                  (is_object($version) ? get_class($version) : gettype($version))
 368              ));
 369          }
 370  
 371          // HTTP/1 uses a "<major>.<minor>" numbering scheme to indicate
 372          // versions of the protocol, while HTTP/2 does not.
 373          if (! preg_match('#^(1\.[01]|2)$#', $version)) {
 374              throw new Exception\InvalidArgumentException(sprintf(
 375                  'Unsupported HTTP protocol version "%s" provided',
 376                  $version
 377              ));
 378          }
 379      }
 380  
 381      /**
 382       * @param mixed $values
 383       * @return string[]
 384       */
 385      private function filterHeaderValue($values) : array
 386      {
 387          if (! is_array($values)) {
 388              $values = [$values];
 389          }
 390  
 391          if ([] === $values) {
 392              throw new Exception\InvalidArgumentException(
 393                  'Invalid header value: must be a string or array of strings; '
 394                  . 'cannot be an empty array'
 395              );
 396          }
 397  
 398          return array_map(function ($value) {
 399              HeaderSecurity::assertValid($value);
 400  
 401              return (string) $value;
 402          }, array_values($values));
 403      }
 404  
 405      /**
 406       * Ensure header name and values are valid.
 407       *
 408       * @param string $name
 409       *
 410       * @throws Exception\InvalidArgumentException
 411       */
 412      private function assertHeader($name) : void
 413      {
 414          HeaderSecurity::assertValidName($name);
 415      }
 416  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer