vendor/guzzlehttp/psr7/src/ServerRequest.php line 75

Open in your IDE?
  1. <?php
  2. namespace GuzzleHttp\Psr7;
  3. use InvalidArgumentException;
  4. use Psr\Http\Message\ServerRequestInterface;
  5. use Psr\Http\Message\StreamInterface;
  6. use Psr\Http\Message\UploadedFileInterface;
  7. use Psr\Http\Message\UriInterface;
  8. /**
  9.  * Server-side HTTP request
  10.  *
  11.  * Extends the Request definition to add methods for accessing incoming data,
  12.  * specifically server parameters, cookies, matched path parameters, query
  13.  * string arguments, body parameters, and upload file information.
  14.  *
  15.  * "Attributes" are discovered via decomposing the request (and usually
  16.  * specifically the URI path), and typically will be injected by the application.
  17.  *
  18.  * Requests are considered immutable; all methods that might change state are
  19.  * implemented such that they retain the internal state of the current
  20.  * message and return a new instance that contains the changed state.
  21.  */
  22. class ServerRequest extends Request implements ServerRequestInterface
  23. {
  24.     /**
  25.      * @var array
  26.      */
  27.     private $attributes = [];
  28.     /**
  29.      * @var array
  30.      */
  31.     private $cookieParams = [];
  32.     /**
  33.      * @var array|object|null
  34.      */
  35.     private $parsedBody;
  36.     /**
  37.      * @var array
  38.      */
  39.     private $queryParams = [];
  40.     /**
  41.      * @var array
  42.      */
  43.     private $serverParams;
  44.     /**
  45.      * @var array
  46.      */
  47.     private $uploadedFiles = [];
  48.     /**
  49.      * @param string                               $method       HTTP method
  50.      * @param string|UriInterface                  $uri          URI
  51.      * @param array                                $headers      Request headers
  52.      * @param string|resource|StreamInterface|null $body         Request body
  53.      * @param string                               $version      Protocol version
  54.      * @param array                                $serverParams Typically the $_SERVER superglobal
  55.      */
  56.     public function __construct(
  57.         $method,
  58.         $uri,
  59.         array $headers = [],
  60.         $body null,
  61.         $version '1.1',
  62.         array $serverParams = []
  63.     ) {
  64.         $this->serverParams $serverParams;
  65.         parent::__construct($method$uri$headers$body$version);
  66.     }
  67.     /**
  68.      * Return an UploadedFile instance array.
  69.      *
  70.      * @param array $files A array which respect $_FILES structure
  71.      *
  72.      * @return array
  73.      *
  74.      * @throws InvalidArgumentException for unrecognized values
  75.      */
  76.     public static function normalizeFiles(array $files)
  77.     {
  78.         $normalized = [];
  79.         foreach ($files as $key => $value) {
  80.             if ($value instanceof UploadedFileInterface) {
  81.                 $normalized[$key] = $value;
  82.             } elseif (is_array($value) && isset($value['tmp_name'])) {
  83.                 $normalized[$key] = self::createUploadedFileFromSpec($value);
  84.             } elseif (is_array($value)) {
  85.                 $normalized[$key] = self::normalizeFiles($value);
  86.                 continue;
  87.             } else {
  88.                 throw new InvalidArgumentException('Invalid value in files specification');
  89.             }
  90.         }
  91.         return $normalized;
  92.     }
  93.     /**
  94.      * Create and return an UploadedFile instance from a $_FILES specification.
  95.      *
  96.      * If the specification represents an array of values, this method will
  97.      * delegate to normalizeNestedFileSpec() and return that return value.
  98.      *
  99.      * @param array $value $_FILES struct
  100.      *
  101.      * @return array|UploadedFileInterface
  102.      */
  103.     private static function createUploadedFileFromSpec(array $value)
  104.     {
  105.         if (is_array($value['tmp_name'])) {
  106.             return self::normalizeNestedFileSpec($value);
  107.         }
  108.         return new UploadedFile(
  109.             $value['tmp_name'],
  110.             (int) $value['size'],
  111.             (int) $value['error'],
  112.             $value['name'],
  113.             $value['type']
  114.         );
  115.     }
  116.     /**
  117.      * Normalize an array of file specifications.
  118.      *
  119.      * Loops through all nested files and returns a normalized array of
  120.      * UploadedFileInterface instances.
  121.      *
  122.      * @param array $files
  123.      *
  124.      * @return UploadedFileInterface[]
  125.      */
  126.     private static function normalizeNestedFileSpec(array $files = [])
  127.     {
  128.         $normalizedFiles = [];
  129.         foreach (array_keys($files['tmp_name']) as $key) {
  130.             $spec = [
  131.                 'tmp_name' => $files['tmp_name'][$key],
  132.                 'size'     => $files['size'][$key],
  133.                 'error'    => $files['error'][$key],
  134.                 'name'     => $files['name'][$key],
  135.                 'type'     => $files['type'][$key],
  136.             ];
  137.             $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
  138.         }
  139.         return $normalizedFiles;
  140.     }
  141.     /**
  142.      * Return a ServerRequest populated with superglobals:
  143.      * $_GET
  144.      * $_POST
  145.      * $_COOKIE
  146.      * $_FILES
  147.      * $_SERVER
  148.      *
  149.      * @return ServerRequestInterface
  150.      */
  151.     public static function fromGlobals()
  152.     {
  153.         $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
  154.         $headers getallheaders();
  155.         $uri self::getUriFromGlobals();
  156.         $body = new CachingStream(new LazyOpenStream('php://input''r+'));
  157.         $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/'''$_SERVER['SERVER_PROTOCOL']) : '1.1';
  158.         $serverRequest = new ServerRequest($method$uri$headers$body$protocol$_SERVER);
  159.         return $serverRequest
  160.             ->withCookieParams($_COOKIE)
  161.             ->withQueryParams($_GET)
  162.             ->withParsedBody($_POST)
  163.             ->withUploadedFiles(self::normalizeFiles($_FILES));
  164.     }
  165.     private static function extractHostAndPortFromAuthority($authority)
  166.     {
  167.         $uri 'http://' $authority;
  168.         $parts parse_url($uri);
  169.         if (false === $parts) {
  170.             return [nullnull];
  171.         }
  172.         $host = isset($parts['host']) ? $parts['host'] : null;
  173.         $port = isset($parts['port']) ? $parts['port'] : null;
  174.         return [$host$port];
  175.     }
  176.     /**
  177.      * Get a Uri populated with values from $_SERVER.
  178.      *
  179.      * @return UriInterface
  180.      */
  181.     public static function getUriFromGlobals()
  182.     {
  183.         $uri = new Uri('');
  184.         $uri $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' 'https' 'http');
  185.         $hasPort false;
  186.         if (isset($_SERVER['HTTP_HOST'])) {
  187.             list($host$port) = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']);
  188.             if ($host !== null) {
  189.                 $uri $uri->withHost($host);
  190.             }
  191.             if ($port !== null) {
  192.                 $hasPort true;
  193.                 $uri $uri->withPort($port);
  194.             }
  195.         } elseif (isset($_SERVER['SERVER_NAME'])) {
  196.             $uri $uri->withHost($_SERVER['SERVER_NAME']);
  197.         } elseif (isset($_SERVER['SERVER_ADDR'])) {
  198.             $uri $uri->withHost($_SERVER['SERVER_ADDR']);
  199.         }
  200.         if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
  201.             $uri $uri->withPort($_SERVER['SERVER_PORT']);
  202.         }
  203.         $hasQuery false;
  204.         if (isset($_SERVER['REQUEST_URI'])) {
  205.             $requestUriParts explode('?'$_SERVER['REQUEST_URI'], 2);
  206.             $uri $uri->withPath($requestUriParts[0]);
  207.             if (isset($requestUriParts[1])) {
  208.                 $hasQuery true;
  209.                 $uri $uri->withQuery($requestUriParts[1]);
  210.             }
  211.         }
  212.         if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
  213.             $uri $uri->withQuery($_SERVER['QUERY_STRING']);
  214.         }
  215.         return $uri;
  216.     }
  217.     /**
  218.      * {@inheritdoc}
  219.      */
  220.     public function getServerParams()
  221.     {
  222.         return $this->serverParams;
  223.     }
  224.     /**
  225.      * {@inheritdoc}
  226.      */
  227.     public function getUploadedFiles()
  228.     {
  229.         return $this->uploadedFiles;
  230.     }
  231.     /**
  232.      * {@inheritdoc}
  233.      */
  234.     public function withUploadedFiles(array $uploadedFiles)
  235.     {
  236.         $new = clone $this;
  237.         $new->uploadedFiles $uploadedFiles;
  238.         return $new;
  239.     }
  240.     /**
  241.      * {@inheritdoc}
  242.      */
  243.     public function getCookieParams()
  244.     {
  245.         return $this->cookieParams;
  246.     }
  247.     /**
  248.      * {@inheritdoc}
  249.      */
  250.     public function withCookieParams(array $cookies)
  251.     {
  252.         $new = clone $this;
  253.         $new->cookieParams $cookies;
  254.         return $new;
  255.     }
  256.     /**
  257.      * {@inheritdoc}
  258.      */
  259.     public function getQueryParams()
  260.     {
  261.         return $this->queryParams;
  262.     }
  263.     /**
  264.      * {@inheritdoc}
  265.      */
  266.     public function withQueryParams(array $query)
  267.     {
  268.         $new = clone $this;
  269.         $new->queryParams $query;
  270.         return $new;
  271.     }
  272.     /**
  273.      * {@inheritdoc}
  274.      */
  275.     public function getParsedBody()
  276.     {
  277.         return $this->parsedBody;
  278.     }
  279.     /**
  280.      * {@inheritdoc}
  281.      */
  282.     public function withParsedBody($data)
  283.     {
  284.         $new = clone $this;
  285.         $new->parsedBody $data;
  286.         return $new;
  287.     }
  288.     /**
  289.      * {@inheritdoc}
  290.      */
  291.     public function getAttributes()
  292.     {
  293.         return $this->attributes;
  294.     }
  295.     /**
  296.      * {@inheritdoc}
  297.      */
  298.     public function getAttribute($attribute$default null)
  299.     {
  300.         if (false === array_key_exists($attribute$this->attributes)) {
  301.             return $default;
  302.         }
  303.         return $this->attributes[$attribute];
  304.     }
  305.     /**
  306.      * {@inheritdoc}
  307.      */
  308.     public function withAttribute($attribute$value)
  309.     {
  310.         $new = clone $this;
  311.         $new->attributes[$attribute] = $value;
  312.         return $new;
  313.     }
  314.     /**
  315.      * {@inheritdoc}
  316.      */
  317.     public function withoutAttribute($attribute)
  318.     {
  319.         if (false === array_key_exists($attribute$this->attributes)) {
  320.             return $this;
  321.         }
  322.         $new = clone $this;
  323.         unset($new->attributes[$attribute]);
  324.         return $new;
  325.     }
  326. }