问题
I try to migrate to 3.4 and I have a problem to send a json object. Up to 3.3, I used the following code:
$jsonSites = json_encode([
'reqLocation' => [
'latitude' => $latitude,
'longitude' => $longitude
],
'sites' => $sitesList,
'discoveryBooks' => $discoveryBooksList,
'deleteSites' => !empty($inDeviceSites) ? [$inDeviceSites] : [],
'deleteBooks' => !empty($inDeviceBooks) ? [$inDeviceBooks] : []
]);
$this->response->type('application/json');
$this->response->body($jsonSites);
And my client received such kind of object:
{
"reqLocation": {
"latitude": 48.080563,
"longitude": 4.4649
},
"sites": [
{
"id": 5076,
"name": "...",
"modified": "2017-01-28T03:03:23+00:00",
"directory_name": "fr/26/26120_56cc30ea4d907",
"type": "portail",
"longitude": 7.031953,
"latitude": 47.939468,
"image_0": "jpg",
"picto_color": "#FFDDDDDD",
"agthemes": [],
"distance": 131.29188575851,
"category": 1281,
"category_name": "Jardin",
"sitecategories": [
{
"id": 10,
"code": 1281,
"name_fr": "Jardin",
"_joinData": {
"id": 1876,
"site_id": 5076,
"site_category_id": 10,
"authorized": true
}
},
{
"id": 33,
"code": 1283,
"name_fr": "Jardin botanique",
"_joinData": {
"id": 5693,
"site_id": 5076,
"site_category_id": 33,
"authorized": true
}
}
]
},
],
"discoveryBooks": [],
"deleteSites": [],
"deleteBooks": []
}
So now I just replaced the deprecated Response methods like that:
EDIT: Of course I return the response object but that cannot work like done here!
$this->response->withType('application/json');
$this->response->withStringBody($jsonSites);
return $this->response;
But now my client doesn't receive anything. I also tried with postman, nothing!
What's wrong?
回答1:
Check the migration guide, the new reponse methods follow the PSR-7 immutability pattern.
Request & Response Deprecations
The bulk of deprecations for 3.4 are in the
Request
andResponse
objects. The existing methods that modify objects in-place are now deprecated, and superseded by methods that follow the immutable object patterns described in the PSR-7 standard.
Cookbook > 3.x Migration Guide > 3.4 Migration Guide > Request & Response Deprecations
Adopting Immutable Responses
Before you migrate your code to use the new response methods you should be aware of the conceptual differences the new methods have. The immutable methods are generally indicated using a with prefix. For example,
withLocation()
. Because these methods operate in an immutable context, they return new instances which you need to assign to variables or properties. If you had controller code that looked like:$response = $this->response; $response->location('/login') $response->header('X-something', 'a value');
If you were to simply find & replace method names your code would break. Instead you must now use code that looks like:
$this->response = $this->response ->withLocation('/login') ->withHeader('X-something', 'a value');
There are a few key differences:
The result of your changes is re-assigned to
$this->response
. This is critical to preserving the intent of the above code. The setter methods can all be chained together. This allows you to skip storing all the intermediate objects.
Cookbook > 3.x Migration Guide > 3.4 Migration Guide > Adopting Immutable Responses
Long story short, in your case you must return the new request object created by the immutable methods:
return $this->response
->withType('application/json');
->withStringBody($jsonSites);
If you wouldn't return a response object, then you'd need to reassign the new reponse to $this->response
as mentioned in the above quote.
来源:https://stackoverflow.com/questions/43184833/cakephp3-4-how-to-send-a-json-object-response