ParameterBag.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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\BadRequestException;
  12. /**
  13. * ParameterBag is a container for key/value pairs.
  14. *
  15. * @author Fabien Potencier <fabien@symfony.com>
  16. *
  17. * @implements \IteratorAggregate<string, mixed>
  18. */
  19. class ParameterBag implements \IteratorAggregate, \Countable
  20. {
  21. /**
  22. * Parameter storage.
  23. */
  24. protected $parameters;
  25. public function __construct(array $parameters = [])
  26. {
  27. $this->parameters = $parameters;
  28. }
  29. /**
  30. * Returns the parameters.
  31. *
  32. * @param string|null $key The name of the parameter to return or null to get them all
  33. *
  34. * @return array
  35. */
  36. public function all(/* string $key = null */)
  37. {
  38. $key = \func_num_args() > 0 ? func_get_arg(0) : null;
  39. if (null === $key) {
  40. return $this->parameters;
  41. }
  42. if (!\is_array($value = $this->parameters[$key] ?? [])) {
  43. throw new BadRequestException(sprintf('Unexpected value for parameter "%s": expecting "array", got "%s".', $key, get_debug_type($value)));
  44. }
  45. return $value;
  46. }
  47. /**
  48. * Returns the parameter keys.
  49. *
  50. * @return array
  51. */
  52. public function keys()
  53. {
  54. return array_keys($this->parameters);
  55. }
  56. /**
  57. * Replaces the current parameters by a new set.
  58. */
  59. public function replace(array $parameters = [])
  60. {
  61. $this->parameters = $parameters;
  62. }
  63. /**
  64. * Adds parameters.
  65. */
  66. public function add(array $parameters = [])
  67. {
  68. $this->parameters = array_replace($this->parameters, $parameters);
  69. }
  70. /**
  71. * Returns a parameter by name.
  72. *
  73. * @param mixed $default The default value if the parameter key does not exist
  74. *
  75. * @return mixed
  76. */
  77. public function get(string $key, $default = null)
  78. {
  79. return \array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
  80. }
  81. /**
  82. * Sets a parameter by name.
  83. *
  84. * @param mixed $value The value
  85. */
  86. public function set(string $key, $value)
  87. {
  88. $this->parameters[$key] = $value;
  89. }
  90. /**
  91. * Returns true if the parameter is defined.
  92. *
  93. * @return bool
  94. */
  95. public function has(string $key)
  96. {
  97. return \array_key_exists($key, $this->parameters);
  98. }
  99. /**
  100. * Removes a parameter.
  101. */
  102. public function remove(string $key)
  103. {
  104. unset($this->parameters[$key]);
  105. }
  106. /**
  107. * Returns the alphabetic characters of the parameter value.
  108. *
  109. * @return string
  110. */
  111. public function getAlpha(string $key, string $default = '')
  112. {
  113. return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default));
  114. }
  115. /**
  116. * Returns the alphabetic characters and digits of the parameter value.
  117. *
  118. * @return string
  119. */
  120. public function getAlnum(string $key, string $default = '')
  121. {
  122. return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default));
  123. }
  124. /**
  125. * Returns the digits of the parameter value.
  126. *
  127. * @return string
  128. */
  129. public function getDigits(string $key, string $default = '')
  130. {
  131. // we need to remove - and + because they're allowed in the filter
  132. return str_replace(['-', '+'], '', $this->filter($key, $default, \FILTER_SANITIZE_NUMBER_INT));
  133. }
  134. /**
  135. * Returns the parameter value converted to integer.
  136. *
  137. * @return int
  138. */
  139. public function getInt(string $key, int $default = 0)
  140. {
  141. return (int) $this->get($key, $default);
  142. }
  143. /**
  144. * Returns the parameter value converted to boolean.
  145. *
  146. * @return bool
  147. */
  148. public function getBoolean(string $key, bool $default = false)
  149. {
  150. return $this->filter($key, $default, \FILTER_VALIDATE_BOOLEAN);
  151. }
  152. /**
  153. * Filter key.
  154. *
  155. * @param mixed $default Default = null
  156. * @param int $filter FILTER_* constant
  157. * @param mixed $options Filter options
  158. *
  159. * @see https://php.net/filter-var
  160. *
  161. * @return mixed
  162. */
  163. public function filter(string $key, $default = null, int $filter = \FILTER_DEFAULT, $options = [])
  164. {
  165. $value = $this->get($key, $default);
  166. // Always turn $options into an array - this allows filter_var option shortcuts.
  167. if (!\is_array($options) && $options) {
  168. $options = ['flags' => $options];
  169. }
  170. // Add a convenience check for arrays.
  171. if (\is_array($value) && !isset($options['flags'])) {
  172. $options['flags'] = \FILTER_REQUIRE_ARRAY;
  173. }
  174. if ((\FILTER_CALLBACK & $filter) && !(($options['options'] ?? null) instanceof \Closure)) {
  175. trigger_deprecation('symfony/http-foundation', '5.2', 'Not passing a Closure together with FILTER_CALLBACK to "%s()" is deprecated. Wrap your filter in a closure instead.', __METHOD__);
  176. // throw new \InvalidArgumentException(sprintf('A Closure must be passed to "%s()" when FILTER_CALLBACK is used, "%s" given.', __METHOD__, get_debug_type($options['options'] ?? null)));
  177. }
  178. return filter_var($value, $filter, $options);
  179. }
  180. /**
  181. * Returns an iterator for parameters.
  182. *
  183. * @return \ArrayIterator<string, mixed>
  184. */
  185. #[\ReturnTypeWillChange]
  186. public function getIterator()
  187. {
  188. return new \ArrayIterator($this->parameters);
  189. }
  190. /**
  191. * Returns the number of parameters.
  192. *
  193. * @return int
  194. */
  195. #[\ReturnTypeWillChange]
  196. public function count()
  197. {
  198. return \count($this->parameters);
  199. }
  200. }