RequestStack.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpFoundation;
  11. use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
  12. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  13. /**
  14. * Request stack that controls the lifecycle of requests.
  15. *
  16. * @author Benjamin Eberlei <kontakt@beberlei.de>
  17. */
  18. class RequestStack
  19. {
  20. /**
  21. * @var Request[]
  22. */
  23. private array $requests = [];
  24. /**
  25. * @param Request[] $requests
  26. */
  27. public function __construct(array $requests = [])
  28. {
  29. foreach ($requests as $request) {
  30. $this->push($request);
  31. }
  32. }
  33. /**
  34. * Pushes a Request on the stack.
  35. *
  36. * This method should generally not be called directly as the stack
  37. * management should be taken care of by the application itself.
  38. */
  39. public function push(Request $request): void
  40. {
  41. $this->requests[] = $request;
  42. }
  43. /**
  44. * Pops the current request from the stack.
  45. *
  46. * This operation lets the current request go out of scope.
  47. *
  48. * This method should generally not be called directly as the stack
  49. * management should be taken care of by the application itself.
  50. */
  51. public function pop(): ?Request
  52. {
  53. if (!$this->requests) {
  54. return null;
  55. }
  56. return array_pop($this->requests);
  57. }
  58. public function getCurrentRequest(): ?Request
  59. {
  60. return end($this->requests) ?: null;
  61. }
  62. /**
  63. * Gets the main request.
  64. *
  65. * Be warned that making your code aware of the main request
  66. * might make it un-compatible with other features of your framework
  67. * like ESI support.
  68. */
  69. public function getMainRequest(): ?Request
  70. {
  71. if (!$this->requests) {
  72. return null;
  73. }
  74. return $this->requests[0];
  75. }
  76. /**
  77. * Returns the parent request of the current.
  78. *
  79. * Be warned that making your code aware of the parent request
  80. * might make it un-compatible with other features of your framework
  81. * like ESI support.
  82. *
  83. * If current Request is the main request, it returns null.
  84. */
  85. public function getParentRequest(): ?Request
  86. {
  87. $pos = \count($this->requests) - 2;
  88. return $this->requests[$pos] ?? null;
  89. }
  90. /**
  91. * Gets the current session.
  92. *
  93. * @throws SessionNotFoundException
  94. */
  95. public function getSession(): SessionInterface
  96. {
  97. if ((null !== $request = end($this->requests) ?: null) && $request->hasSession()) {
  98. return $request->getSession();
  99. }
  100. throw new SessionNotFoundException();
  101. }
  102. public function resetRequestFormats(): void
  103. {
  104. static $resetRequestFormats;
  105. $resetRequestFormats ??= \Closure::bind(static fn () => self::$formats = null, null, Request::class);
  106. $resetRequestFormats();
  107. }
  108. }