Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 050e889

Browse files
committed
Serialize without casting.
As noted on #63, scalars and nulls can be serialized by PHP, and most (all?) client-side parsers will deserialize them correctly. As such, the more correct route is to pass them verbatim to `json_encode()` instead of casting them to arrays and/or objects.
1 parent 150d25f commit 050e889

File tree

3 files changed

+11
-31
lines changed

3 files changed

+11
-31
lines changed

doc/book/custom-responses.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ the `Content-Type` header to `application/json`:
5252
$response = new JsonResponse($data);
5353
```
5454

55-
If a null value is provide, an empty JSON object is used for the content. Scalar data is cast to an
56-
array before serialization. If providing an object, we recommend implementing
57-
[JsonSerializable](http://php.net/JsonSerializable) to ensure your object is correctly serialized.
55+
If providing an object, we recommend implementing [JsonSerializable](http://php.net/JsonSerializable)
56+
to ensure your object is correctly serialized.
5857

5958
Just like the `HtmlResponse`, the `JsonResponse` allows passing two additional arguments — a
6059
status code, and an array of headers — to allow you to further seed the initial state of the

src/Response/JsonResponse.php

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,23 @@
99

1010
namespace Zend\Diactoros\Response;
1111

12-
use ArrayObject;
1312
use InvalidArgumentException;
1413
use Zend\Diactoros\Response;
1514
use Zend\Diactoros\Stream;
1615

1716
/**
18-
* HTML response.
17+
* JSON response.
1918
*
20-
* Allows creating a response by passing an HTML string to the constructor;
21-
* by default, sets a status code of 200 and sets the Content-Type header to
22-
* text/html.
19+
* Allows creating a response by passing data to the constructor; by default,
20+
* serializes the data to JSON, sets a status code of 200 and sets the
21+
* Content-Type header to application/json.
2322
*/
2423
class JsonResponse extends Response
2524
{
2625
use InjectContentTypeTrait;
2726

2827
/**
29-
* Create a JSON response with the given array of data.
30-
*
31-
* If the data provided is null, an empty ArrayObject is used; if the data
32-
* is scalar, it is cast to an array prior to serialization.
28+
* Create a JSON response with the given data.
3329
*
3430
* Default JSON encoding is performed with the following options, which
3531
* produces RFC4627-compliant JSON, capable of embedding into HTML.
@@ -69,15 +65,6 @@ private function jsonEncode($data, $encodingOptions)
6965
throw new InvalidArgumentException('Cannot JSON encode resources');
7066
}
7167

72-
if ($data === null) {
73-
// Use an ArrayObject to force an empty JSON object.
74-
$data = new ArrayObject();
75-
}
76-
77-
if (is_scalar($data)) {
78-
$data = (array) $data;
79-
}
80-
8168
// Clear json_last_error()
8269
json_encode(null);
8370

test/Response/JsonResponseTest.php

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,10 @@ public function testConstructorAcceptsDataAndCreatesJsonEncodedMessageBody()
3131
$this->assertSame($json, (string) $response->getBody());
3232
}
3333

34-
public function testNullValuePassedToConstructorRendersEmptyJsonObjectInBody()
35-
{
36-
$response = new JsonResponse(null);
37-
$this->assertEquals(200, $response->getStatusCode());
38-
$this->assertEquals('application/json', $response->getHeaderLine('content-type'));
39-
$this->assertSame('{}', (string) $response->getBody());
40-
}
41-
4234
public function scalarValuesForJSON()
4335
{
4436
return [
37+
'null' => [null],
4538
'false' => [false],
4639
'true' => [true],
4740
'zero' => [0],
@@ -56,12 +49,13 @@ public function scalarValuesForJSON()
5649
/**
5750
* @dataProvider scalarValuesForJSON
5851
*/
59-
public function testScalarValuePassedToConstructorRendersValueWithinJSONArray($value)
52+
public function testScalarValuePassedToConstructorJsonEncodesDirectly($value)
6053
{
6154
$response = new JsonResponse($value);
6255
$this->assertEquals(200, $response->getStatusCode());
6356
$this->assertEquals('application/json', $response->getHeaderLine('content-type'));
64-
$this->assertSame(json_encode([$value], JSON_UNESCAPED_SLASHES), (string) $response->getBody());
57+
// 15 is the default mask used by JsonResponse
58+
$this->assertSame(json_encode($value, 15), (string) $response->getBody());
6559
}
6660

6761
public function testCanProvideStatusCodeToConstructor()

0 commit comments

Comments
 (0)