minor #40315 [HttpFoundation] Use InputBag for POST requests too (acasademont)

This PR was merged into the 5.3-dev branch.

Discussion
----------

[HttpFoundation] Use InputBag for POST requests too

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | Partially revert #37265
| License       | MIT
| Doc PR        | -

#37265 was created as a fix for #37100. However, when #37327 was merged, the original bug was also fixed with a different solution (allowing null values on `InputBag::set`) and parts of #37265 are not needed anymore. By using only `InputBag` as the `$request` bag we can tighten the typehint again and make static analysis a bit more useful.

Commits
-------

381a0a19f7 use InputBag for POST requests too, added missing scalar type hints
This commit is contained in:
Fabien Potencier 2021-03-12 09:36:26 +01:00
commit 7754beddfc
4 changed files with 19 additions and 23 deletions

View File

@ -21,16 +21,16 @@ use Symfony\Component\HttpFoundation\Exception\BadRequestException;
final class InputBag extends ParameterBag final class InputBag extends ParameterBag
{ {
/** /**
* Returns a string input value by name. * Returns a scalar input value by name.
* *
* @param string|null $default The default value if the input key does not exist * @param string|int|float|bool|null $default The default value if the input key does not exist
* *
* @return string|null * @return string|int|float|bool|null
*/ */
public function get(string $key, $default = null) public function get(string $key, $default = null)
{ {
if (null !== $default && !is_scalar($default) && !(\is_object($default) && method_exists($default, '__toString'))) { if (null !== $default && !is_scalar($default) && !(\is_object($default) && method_exists($default, '__toString'))) {
trigger_deprecation('symfony/http-foundation', '5.1', 'Passing a non-string value as 2nd argument to "%s()" is deprecated, pass a string or null instead.', __METHOD__); trigger_deprecation('symfony/http-foundation', '5.1', 'Passing a non-scalar value as 2nd argument to "%s()" is deprecated, pass a scalar or null instead.', __METHOD__);
} }
$value = parent::get($key, $this); $value = parent::get($key, $this);
@ -72,12 +72,12 @@ final class InputBag extends ParameterBag
/** /**
* Sets an input by name. * Sets an input by name.
* *
* @param string|array|null $value * @param string|int|float|bool|array|null $value
*/ */
public function set(string $key, $value) public function set(string $key, $value)
{ {
if (null !== $value && !is_scalar($value) && !\is_array($value) && !method_exists($value, '__toString')) { if (null !== $value && !is_scalar($value) && !\is_array($value) && !method_exists($value, '__toString')) {
trigger_deprecation('symfony/http-foundation', '5.1', 'Passing "%s" as a 2nd Argument to "%s()" is deprecated, pass a string, array, or null instead.', get_debug_type($value), __METHOD__); trigger_deprecation('symfony/http-foundation', '5.1', 'Passing "%s" as a 2nd Argument to "%s()" is deprecated, pass a scalar, array, or null instead.', get_debug_type($value), __METHOD__);
} }
$this->parameters[$key] = $value; $this->parameters[$key] = $value;

View File

@ -91,7 +91,7 @@ class Request
/** /**
* Request body parameters ($_POST). * Request body parameters ($_POST).
* *
* @var InputBag|ParameterBag * @var InputBag
*/ */
public $request; public $request;
@ -275,7 +275,7 @@ class Request
*/ */
public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null) public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
{ {
$this->request = new ParameterBag($request); $this->request = new InputBag($request);
$this->query = new InputBag($query); $this->query = new InputBag($query);
$this->attributes = new ParameterBag($attributes); $this->attributes = new ParameterBag($attributes);
$this->cookies = new InputBag($cookies); $this->cookies = new InputBag($cookies);
@ -305,9 +305,7 @@ class Request
{ {
$request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER); $request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);
if ($_POST) { if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
$request->request = new InputBag($_POST);
} elseif (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
&& \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH']) && \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'])
) { ) {
parse_str($request->getContent(), $data); parse_str($request->getContent(), $data);
@ -457,7 +455,7 @@ class Request
$dup->query = new InputBag($query); $dup->query = new InputBag($query);
} }
if (null !== $request) { if (null !== $request) {
$dup->request = new ParameterBag($request); $dup->request = new InputBag($request);
} }
if (null !== $attributes) { if (null !== $attributes) {
$dup->attributes = new ParameterBag($attributes); $dup->attributes = new ParameterBag($attributes);

View File

@ -21,11 +21,14 @@ class InputBagTest extends TestCase
public function testGet() public function testGet()
{ {
$bag = new InputBag(['foo' => 'bar', 'null' => null]); $bag = new InputBag(['foo' => 'bar', 'null' => null, 'int' => 1, 'float' => 1.0, 'bool' => false]);
$this->assertEquals('bar', $bag->get('foo'), '->get() gets the value of a parameter'); $this->assertSame('bar', $bag->get('foo'), '->get() gets the value of a string parameter');
$this->assertEquals('default', $bag->get('unknown', 'default'), '->get() returns second argument as default if a parameter is not defined'); $this->assertSame('default', $bag->get('unknown', 'default'), '->get() returns second argument as default if a parameter is not defined');
$this->assertNull($bag->get('null', 'default'), '->get() returns null if null is set'); $this->assertNull($bag->get('null', 'default'), '->get() returns null if null is set');
$this->assertSame(1, $bag->get('int'), '->get() gets the value of an int parameter');
$this->assertSame(1.0, $bag->get('float'), '->get() gets the value of a float parameter');
$this->assertFalse($bag->get('bool'), '->get() gets the value of a bool parameter');
} }
public function testGetDoesNotUseDeepByDefault() public function testGetDoesNotUseDeepByDefault()
@ -59,10 +62,10 @@ class InputBagTest extends TestCase
/** /**
* @group legacy * @group legacy
*/ */
public function testSetWithNonStringishOrArrayIsDeprecated() public function testSetWithNonScalarOrArrayIsDeprecated()
{ {
$bag = new InputBag(); $bag = new InputBag();
$this->expectDeprecation('Since symfony/http-foundation 5.1: Passing "Symfony\Component\HttpFoundation\InputBag" as a 2nd Argument to "Symfony\Component\HttpFoundation\InputBag::set()" is deprecated, pass a string, array, or null instead.'); $this->expectDeprecation('Since symfony/http-foundation 5.1: Passing "Symfony\Component\HttpFoundation\InputBag" as a 2nd Argument to "Symfony\Component\HttpFoundation\InputBag::set()" is deprecated, pass a scalar, array, or null instead.');
$bag->set('foo', new InputBag()); $bag->set('foo', new InputBag());
} }
@ -82,7 +85,7 @@ class InputBagTest extends TestCase
public function testGetWithNonStringDefaultValueIsDeprecated() public function testGetWithNonStringDefaultValueIsDeprecated()
{ {
$bag = new InputBag(['foo' => 'bar']); $bag = new InputBag(['foo' => 'bar']);
$this->expectDeprecation('Since symfony/http-foundation 5.1: Passing a non-string value as 2nd argument to "Symfony\Component\HttpFoundation\InputBag::get()" is deprecated, pass a string or null instead.'); $this->expectDeprecation('Since symfony/http-foundation 5.1: Passing a non-scalar value as 2nd argument to "Symfony\Component\HttpFoundation\InputBag::get()" is deprecated, pass a scalar or null instead.');
$bag->get('foo', ['a', 'b']); $bag->get('foo', ['a', 'b']);
} }

View File

@ -1287,11 +1287,6 @@ class RequestTest extends TestCase
{ {
$normalizedMethod = strtoupper($method); $normalizedMethod = strtoupper($method);
$_POST = [];
$request = Request::createFromGlobals();
$this->assertNotInstanceOf(InputBag::class, $request->request);
$this->assertInstanceOf(ParameterBag::class, $request->request);
$_GET['foo1'] = 'bar1'; $_GET['foo1'] = 'bar1';
$_POST['foo2'] = 'bar2'; $_POST['foo2'] = 'bar2';
$_COOKIE['foo3'] = 'bar3'; $_COOKIE['foo3'] = 'bar3';