CakePHP3.4:如何发送 json 对象响应?

CakePHP3.4: How to send a json object response?

我尝试迁移到 3.4,但在发送 json 对象时遇到问题。 到3.3为止,我用了下面的代码:

$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);

我的客户收到了这样的对象:

{
  "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": []
}

所以现在我只是像这样替换了已弃用的响应方法:

编辑: 当然我 return 响应对象但是不能像这里那样工作!

$this->response->withType('application/json');
$this->response->withStringBody($jsonSites);
return $this->response;

但是现在我的客户没有收到任何东西。我也试过邮递员,没有!

怎么了?

查看迁移指南,新的响应方法遵循 PSR-7 不变性模式。

Request & Response Deprecations

The bulk of deprecations for 3.4 are in the Request and Response 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

长话短说,在您的情况下,您必须 return 由不可变方法创建的新请求对象:

return $this->response
    ->withType('application/json');
    ->withStringBody($jsonSites);

如果您不想 return 一个响应对象,那么您需要将新的响应重新分配给 $this->response,如上面引用中所述。