Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f589ff4

Browse files
committed
feature #38224 [HttpFoundation] Add Request::toArray() for JSON content (Nyholm)
This PR was squashed before being merged into the 5.2-dev branch. Discussion ---------- [HttpFoundation] Add Request::toArray() for JSON content | Q | A | ------------- | --- | Branch? | master | Bug fix? | ni | New feature? | yes | Deprecations? | no | Tickets | | License | MIT | Doc PR | The past few months I've been working more and more with javascript and APIs. I've written controllers that parse json from the request body. I've found myself copying code between projects so I looked at the possibility to add this code to the `Request` class itself. ### Usage ```http POST /add-user Content-Type: application/json {"name": "Tobias", "email": "[email protected]"} ``` ```php use Symfony\Component\HttpFoundation\Exception\JsonException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\JsonResponse; class MyController // ... public function addUser(Request $request): JsonResponse { try { $data = $request->toArray(); } catch (JsonException $e) { return new JsonResponse(['message'=>'Request does not contain valid json'], 415); } $command = new AddUser($data['email'] ?? '', $data['name'] ?? ''); try { $this->commandBus->dispatch($command); } catch (ValidationFailedException $e) { return new JsonResponse(['message' => 'Unexpected JSON body'], 400); } return new JsonResponse(['message' => 'User successfully added']); } } ``` ---------- I've searched but I have not found that this has been proposed before.. With is strange.. ¯\\_(ツ)_/¯ Commits ------- 83c1a26 [HttpFoundation] Add Request::toArray() for JSON content
2 parents f8b1543 + 83c1a26 commit f589ff4

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

src/Symfony/Component/HttpFoundation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* added `HeaderUtils::parseQuery()`: it does the same as `parse_str()` but preserves dots in variable names
99
* added `File::getContent()`
1010
* added ability to use comma separated ip addresses for `RequestMatcher::matchIps()`
11+
* added `Request::toArray()` to parse a JSON request body to an array
1112
* added `RateLimiter\RequestRateLimiterInterface` and `RateLimiter\AbstractRequestRateLimiter`
1213

1314
5.1.0
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpFoundation\Exception;
13+
14+
/**
15+
* Thrown by Request::toArray() when the content cannot be JSON-decoded.
16+
*
17+
* @author Tobias Nyholm <[email protected]>
18+
*/
19+
final class JsonException extends \UnexpectedValueException implements RequestExceptionInterface
20+
{
21+
}

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\HttpFoundation;
1313

1414
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
15+
use Symfony\Component\HttpFoundation\Exception\JsonException;
1516
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
1617
use Symfony\Component\HttpFoundation\Session\SessionInterface;
1718

@@ -1569,6 +1570,34 @@ public function getContent(bool $asResource = false)
15691570
return $this->content;
15701571
}
15711572

1573+
/**
1574+
* Gets the request body decoded as array, typically from a JSON payload.
1575+
*
1576+
* @throws JsonException When the body cannot be decoded to an array
1577+
*/
1578+
public function toArray(): array
1579+
{
1580+
if ('' === $content = $this->getContent()) {
1581+
throw new JsonException('Response body is empty.');
1582+
}
1583+
1584+
try {
1585+
$content = json_decode($content, true, 512, \JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0));
1586+
} catch (\JsonException $e) {
1587+
throw new JsonException('Could not decode request body.', $e->getCode(), $e);
1588+
}
1589+
1590+
if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error()) {
1591+
throw new JsonException('Could not decode request body: '.json_last_error_msg(), json_last_error());
1592+
}
1593+
1594+
if (!\is_array($content)) {
1595+
throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content)));
1596+
}
1597+
1598+
return $content;
1599+
}
1600+
15721601
/**
15731602
* Gets the Etags.
15741603
*

src/Symfony/Component/HttpFoundation/Tests/RequestTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\HttpFoundation\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Exception\JsonException;
1516
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
1617
use Symfony\Component\HttpFoundation\InputBag;
1718
use Symfony\Component\HttpFoundation\ParameterBag;
@@ -1250,6 +1251,30 @@ public function provideOverloadedMethods()
12501251
];
12511252
}
12521253

1254+
public function testToArrayEmpty()
1255+
{
1256+
$req = new Request();
1257+
$this->expectException(JsonException::class);
1258+
$this->expectExceptionMessage('Response body is empty.');
1259+
$req->toArray();
1260+
}
1261+
1262+
public function testToArrayNonJson()
1263+
{
1264+
$req = new Request([], [], [], [], [], [], 'foobar');
1265+
$this->expectException(JsonException::class);
1266+
$this->expectExceptionMessageMatches('|Could not decode request body.+|');
1267+
$req->toArray();
1268+
}
1269+
1270+
public function testToArray()
1271+
{
1272+
$req = new Request([], [], [], [], [], [], json_encode([]));
1273+
$this->assertEquals([], $req->toArray());
1274+
$req = new Request([], [], [], [], [], [], json_encode(['foo' => 'bar']));
1275+
$this->assertEquals(['foo' => 'bar'], $req->toArray());
1276+
}
1277+
12531278
/**
12541279
* @dataProvider provideOverloadedMethods
12551280
*/

0 commit comments

Comments
 (0)