RedirectResponse.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. /**
  12. * RedirectResponse represents an HTTP response doing a redirect.
  13. *
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. */
  16. class RedirectResponse extends Response
  17. {
  18. protected $targetUrl;
  19. /**
  20. * Creates a redirect response so that it conforms to the rules defined for a redirect status code.
  21. *
  22. * @param string $url The URL to redirect to. The URL should be a full URL, with schema etc.,
  23. * but practically every browser redirects on paths only as well
  24. * @param int $status The status code (302 by default)
  25. * @param array $headers The headers (Location is always set to the given URL)
  26. *
  27. * @throws \InvalidArgumentException
  28. *
  29. * @see https://tools.ietf.org/html/rfc2616#section-10.3
  30. */
  31. public function __construct(?string $url, int $status = 302, array $headers = [])
  32. {
  33. if (null === $url) {
  34. @trigger_error(sprintf('Passing a null url when instantiating a "%s" is deprecated since Symfony 4.4.', __CLASS__), \E_USER_DEPRECATED);
  35. $url = '';
  36. }
  37. parent::__construct('', $status, $headers);
  38. $this->setTargetUrl($url);
  39. if (!$this->isRedirect()) {
  40. throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
  41. }
  42. if (301 == $status && !\array_key_exists('cache-control', array_change_key_case($headers, \CASE_LOWER))) {
  43. $this->headers->remove('cache-control');
  44. }
  45. }
  46. /**
  47. * Factory method for chainability.
  48. *
  49. * @param string $url The url to redirect to
  50. * @param int $status The response status code
  51. * @param array $headers An array of response headers
  52. *
  53. * @return static
  54. */
  55. public static function create($url = '', $status = 302, $headers = [])
  56. {
  57. return new static($url, $status, $headers);
  58. }
  59. /**
  60. * Returns the target URL.
  61. *
  62. * @return string target URL
  63. */
  64. public function getTargetUrl()
  65. {
  66. return $this->targetUrl;
  67. }
  68. /**
  69. * Sets the redirect target of this response.
  70. *
  71. * @param string $url The URL to redirect to
  72. *
  73. * @return $this
  74. *
  75. * @throws \InvalidArgumentException
  76. */
  77. public function setTargetUrl($url)
  78. {
  79. if ('' === ($url ?? '')) {
  80. throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
  81. }
  82. $this->targetUrl = $url;
  83. $this->setContent(
  84. sprintf('<!DOCTYPE html>
  85. <html>
  86. <head>
  87. <meta charset="UTF-8" />
  88. <meta http-equiv="refresh" content="0;url=\'%1$s\'" />
  89. <title>Redirecting to %1$s</title>
  90. </head>
  91. <body>
  92. Redirecting to <a href="%1$s">%1$s</a>.
  93. </body>
  94. </html>', htmlspecialchars($url, \ENT_QUOTES, 'UTF-8')));
  95. $this->headers->set('Location', $url);
  96. return $this;
  97. }
  98. }