Skip to content

[HttpFoundation] Deprecate \Stringable support in InputBag #47087

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions UPGRADE-6.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ HttpFoundation
--------------

* Deprecate `Request::getContentType()`, use `Request::getContentTypeFormat()` instead
* Deprecate passing `\Stringable` objects to `InputBag`, use scalars, arrays or null instead.

Mailer
--------
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/HttpFoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

6.2
---

* Deprecate passing `\Stringable` objects to `InputBag`, use scalars, arrays or null instead.

6.1
---

Expand Down
16 changes: 16 additions & 0 deletions src/Symfony/Component/HttpFoundation/InputBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,26 @@ final class InputBag extends ParameterBag
*/
public function get(string $key, mixed $default = null): string|int|float|bool|null
{
// @deprecated since symfony 6.2, in 7.0 change to:
// if (null !== $default && !\is_scalar($default)) {
if (null !== $default && !\is_scalar($default) && !$default instanceof \Stringable) {
throw new \InvalidArgumentException(sprintf('Expected a scalar value as a 2nd argument to "%s()", "%s" given.', __METHOD__, get_debug_type($default)));
}

if ($default instanceof \Stringable) {
trigger_deprecation('symfony/http-foundation', '6.2', 'Passing a "%s" object as 2nd argument ($default) to "%s()" is deprecated, pass a scalar or null instead.', get_debug_type($default), __METHOD__);
}

$value = parent::get($key, $this);

if (null !== $value && $this !== $value && !\is_scalar($value) && !$value instanceof \Stringable) {
throw new BadRequestException(sprintf('Input value "%s" contains a non-scalar value.', $key));
}

if ($value instanceof \Stringable) {
trigger_deprecation('symfony/http-foundation', '6.2', 'Retrieving a "%s" object from "%s()" is deprecated, use scalars or null instead.', get_debug_type($value), __METHOD__);
}

return $this === $value ? $default : $value;
}

Expand Down Expand Up @@ -66,10 +76,16 @@ public function add(array $inputs = [])
*/
public function set(string $key, mixed $value)
{
// @deprecated since symfony 6.2, in 7.0 change to:
// if (null !== $value && !\is_scalar($value) && !\is_array($value)) {
if (null !== $value && !\is_scalar($value) && !\is_array($value) && !$value instanceof \Stringable) {
throw new \InvalidArgumentException(sprintf('Expected a scalar, or an array as a 2nd argument to "%s()", "%s" given.', __METHOD__, get_debug_type($value)));
}

if ($value instanceof \Stringable) {
trigger_deprecation('symfony/http-foundation', '6.2', 'Passing a "%s" object as a 2nd argument ($value) to "%s()" is deprecated. Pass a scalar, an array or null instead.', get_debug_type($value), __METHOD__);
}

$this->parameters[$key] = $value;
}

Expand Down
42 changes: 35 additions & 7 deletions src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,23 @@
namespace Symfony\Component\HttpFoundation\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\InputBag;

class InputBagTest extends TestCase
{
use ExpectDeprecationTrait;

public function testGet()
{
$bag = new InputBag(['foo' => 'bar', 'null' => null, 'int' => 1, 'float' => 1.0, 'bool' => false, 'stringable' => new class() implements \Stringable {
public function __toString(): string
{
return 'strval';
}
}]);
$bag = new InputBag(['foo' => 'bar', 'null' => null, 'int' => 1, 'float' => 1.0, 'bool' => false]);

$this->assertSame('bar', $bag->get('foo'), '->get() gets the value of a string parameter');
$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->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->assertSame('strval', $bag->get('stringable'), '->get() gets the string value of a \Stringable parameter');
$this->assertFalse($bag->get('bool'), '->get() gets the value of a bool parameter');
}

Expand Down Expand Up @@ -106,4 +103,35 @@ public function testFilterArrayWithoutArrayFlag()
$bag = new InputBag(['foo' => ['bar', 'baz']]);
$bag->filter('foo', \FILTER_VALIDATE_INT);
}

/**
* @group legacy
*/
public function testLegacyGetStringableObject()
{
$bag = new InputBag(['stringable' => new class() implements \Stringable {
public function __toString(): string
{
return 'strval';
}
}]);

$this->expectDeprecation('Since symfony/http-foundation 6.2: Retrieving a "Stringable@anonymous" object from "Symfony\Component\HttpFoundation\InputBag::get()" is deprecated, use scalars or null instead.');
$this->assertSame('strval', $bag->get('stringable'), '->get() gets the string value of a \Stringable parameter');
}

/**
* @group legacy
*/
public function testLegacySetStringableObject()
{
$bag = new InputBag();
$this->expectDeprecation('Since symfony/http-foundation 6.2: Passing a "Stringable@anonymous" object as a 2nd argument ($value) to "Symfony\Component\HttpFoundation\InputBag::set()" is deprecated. Pass a scalar, an array or null instead.');
$bag->set('stringable', new class() implements \Stringable {
public function __toString(): string
{
return 'strval';
}
});
}
}