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

Posted

技术标签:

【中文标题】CakePHP3.4:如何发送 json 对象响应?【英文标题】:CakePHP3.4: How to send a json object response? 【发布时间】:2017-08-28 07:57:36 【问题描述】:

我尝试迁移到 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": []

所以现在我只是替换了不推荐使用的响应方法:

编辑:我当然会返回响应对象,但不能像这里那样工作!

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

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

怎么了?

【问题讨论】:

【参考方案1】:

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

请求和响应弃用

3.4 的大部分弃用位于 RequestResponse 对象。就地修改对象的现有方法现在是 不推荐使用,并被不可变对象之后的方法取代 PSR-7 标准中描述的模式。

Cookbook > 3.x Migration Guide > 3.4 Migration Guide > Request & Response Deprecations

采用不可变响应

在迁移代码以使用新的响应方法之前,您 应该注意新方法的概念差异。 不可变方法通常使用 with 前缀表示。为了 例如,withLocation()。因为这些方法以不可变的方式运行 上下文,它们返回您需要分配给的新实例 变量或属性。如果您的控制器代码如下所示:

$response = $this->response;
$response->location('/login')
$response->header('X-something', 'a value');

如果您只是简单地查找和替换方法名称,您的代码就会中断。 相反,您现在必须使用如下代码:

$this->response = $this->response
    ->withLocation('/login')
    ->withHeader('X-something', 'a value');

有几个关键区别:

您的更改结果将重新分配给$this->response。这是 对保留上述代码的意图至关重要。二传手 方法都可以链接在一起。这允许您跳过存储 所有中间对象。

Cookbook > 3.x Migration Guide > 3.4 Migration Guide > Adopting Immutable Responses

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

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

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

【讨论】:

以上是关于CakePHP3.4:如何发送 json 对象响应?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据请求从 JS 文件发送 JSON 响应?

如何使用 Android 通过 Request 发送 JSON 对象?

如何获取第一数据 JSON 响应对象属性?

Retrofit2:如何在具有不同字段名称的对象中接收 JSON 响应?

如何将java json对象数据发送到android api请求

忽略要在 JSON 响应中发送的父对象 - 循环问题 - JPA