ServerRequestFactory.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /**
  3. * Slim Framework (https://slimframework.com)
  4. *
  5. * @license https://github.com/slimphp/Slim-Psr7/blob/master/LICENSE.md (MIT License)
  6. */
  7. declare(strict_types=1);
  8. namespace Slim\Psr7\Factory;
  9. use InvalidArgumentException;
  10. use Psr\Http\Message\ServerRequestFactoryInterface;
  11. use Psr\Http\Message\ServerRequestInterface;
  12. use Psr\Http\Message\StreamFactoryInterface;
  13. use Psr\Http\Message\UriFactoryInterface;
  14. use Psr\Http\Message\UriInterface;
  15. use Slim\Psr7\Cookies;
  16. use Slim\Psr7\Headers;
  17. use Slim\Psr7\Request;
  18. use Slim\Psr7\Stream;
  19. use Slim\Psr7\UploadedFile;
  20. use function current;
  21. use function explode;
  22. use function fopen;
  23. use function in_array;
  24. use function is_string;
  25. class ServerRequestFactory implements ServerRequestFactoryInterface
  26. {
  27. /**
  28. * @var StreamFactoryInterface|StreamFactory
  29. */
  30. protected $streamFactory;
  31. /**
  32. * @var UriFactoryInterface|UriFactory
  33. */
  34. protected $uriFactory;
  35. /**
  36. * @param StreamFactoryInterface|null $streamFactory
  37. * @param UriFactoryInterface|null $uriFactory
  38. */
  39. public function __construct(?StreamFactoryInterface $streamFactory = null, ?UriFactoryInterface $uriFactory = null)
  40. {
  41. if (!isset($streamFactory)) {
  42. $streamFactory = new StreamFactory();
  43. }
  44. if (!isset($uriFactory)) {
  45. $uriFactory = new UriFactory();
  46. }
  47. $this->streamFactory = $streamFactory;
  48. $this->uriFactory = $uriFactory;
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
  54. {
  55. if (is_string($uri)) {
  56. $uri = $this->uriFactory->createUri($uri);
  57. }
  58. if (!$uri instanceof UriInterface) {
  59. throw new InvalidArgumentException('URI must either be string or instance of ' . UriInterface::class);
  60. }
  61. $body = $this->streamFactory->createStream();
  62. $headers = new Headers();
  63. $cookies = [];
  64. if (!empty($serverParams)) {
  65. $headers = Headers::createFromGlobals();
  66. $cookies = Cookies::parseHeader($headers->getHeader('Cookie', []));
  67. }
  68. return new Request($method, $uri, $headers, $cookies, $serverParams, $body);
  69. }
  70. /**
  71. * Create new ServerRequest from environment.
  72. *
  73. * @internal This method is not part of PSR-17
  74. *
  75. * @return Request
  76. */
  77. public static function createFromGlobals(): Request
  78. {
  79. $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
  80. $uri = (new UriFactory())->createFromGlobals($_SERVER);
  81. $headers = Headers::createFromGlobals();
  82. $cookies = Cookies::parseHeader($headers->getHeader('Cookie', []));
  83. // Cache the php://input stream as it cannot be re-read
  84. $cacheResource = fopen('php://temp', 'wb+');
  85. $cache = $cacheResource ? new Stream($cacheResource) : null;
  86. $body = (new StreamFactory())->createStreamFromFile('php://input', 'r', $cache);
  87. $uploadedFiles = UploadedFile::createFromGlobals($_SERVER);
  88. $request = new Request($method, $uri, $headers, $cookies, $_SERVER, $body, $uploadedFiles);
  89. $contentTypes = $request->getHeader('Content-Type') ?? [];
  90. $parsedContentType = '';
  91. foreach ($contentTypes as $contentType) {
  92. $fragments = explode(';', $contentType);
  93. $parsedContentType = current($fragments);
  94. }
  95. $contentTypesWithParsedBodies = ['application/x-www-form-urlencoded', 'multipart/form-data'];
  96. if ($method === 'POST' && in_array($parsedContentType, $contentTypesWithParsedBodies)) {
  97. return $request->withParsedBody($_POST);
  98. }
  99. return $request;
  100. }
  101. }