[CakePHP4] json 出力で Notice: Deprecated "_serialize" が出たので ViewBuilder::setOptionを使う

debug.log を見ていた同僚から以下の `Notice: Deprecated` を教えてもらい対応しました。
検索しても `ViewBuilder::setOption('serialize', $value)` の事例がなかったので備忘録です。
今後は CI で気付けるようにしたいと思います。

# Notice: Deprecated (16384): Setting special view var "_serialize" is deprecated.
Notice だけ抜粋します。（実際のURLなどは加工しています）

```log
2020-11-09 04:05:26 Notice: Deprecated (16384): Setting special view var "_serialize" is deprecated. Use ViewBuilder::setOption('serialize', $value) instead. - /var/www/app/vendor/cakephp/cakephp/src/View/SerializedView.php, line: 68
 You can disable deprecation warnings by setting `Error.errorLevel` to `E_ALL & ~E_USER_DEPRECATED` in your config/app.php. in [/var/www/app/vendor/cakephp/cakephp/src/Core/functions.php, line 305]Request URL: /users/request-url
```

## 概要
- json 出力に "_serialize" を使うのは非推奨
- `ViewBuilder::setOption('serialize', $value)` を使いましょう

# 公式
CakePHP 3.9 までは以下の書き方だったようです。
https://book.cakephp.org/3/ja/views/json-and-xml-views.html#id2

が、CakePHP 4 になり `_serialize` が非推奨となりました。
https://book.cakephp.org/4/ja/appendices/4-0-migration-guide.html#view

> JsonView の特別なビュー変数 _serialize 、 _jsonOptions および _jsonp は非推奨になりました。 代わりに、 `viewBuilder()->setOption($optionName, $optionValue)` を、それらのオプションを設定するために使用してください。

しかし CakePHP 4 のドキュメントは以下なので混乱しますね。
https://book.cakephp.org/4/ja/views/json-and-xml-views.html#json

# コード
以下、Controller で記述するものとします。

## 修正前

```php
$this->viewBuilder()->setClassName('Json');

if (!$this->changeUserStatus($id, $status)) {
    $result = false;
    $message = 'エラーが発生しました';
}

$this->set([
    'result' => $result,
    'message' => $message,
    '_serialize' => ['result', 'message'],
]);
```

## 修正後

```php
$this->viewBuilder()->setClassName('Json');

(中略)

$this->set('result', $result);
$this->set('message', $message);
$this->viewBuilder()->setOption('serialize', ['result', 'message']);
```

# 余談
`viewBuilder()->setOption` に Entity の配列を渡しても、いい感じに JSON に変換してくれます。

- Controller
    - debug してるので header の Warning が出ますがご容赦を

```php
// 例えば user の Entity の配列
$users = $this->Users->find()->select(['id', 'email', 'status', 'created', 'modified'])->limit(2)->toList();
debug($users);
$this->set('result', true);
$this->set('message', 'Entity の配列変換テスト');
$this->set('users', $users);
$this->viewBuilder()->setOption('serialize', ['result', 'message', 'users']);
```

- debug 表示

```javascript
[
    (int) 0 => object(App\Model\Entity\User) id:0 {
        'id' => (int) 1
        'nickname' => 'nickname_1'
        'email' => 'test+1@lancers.co.jp'
        'status' => 'active'
        'created' => object(Cake\I18n\FrozenTime) id:3 { }
        'modified' => object(Cake\I18n\FrozenTime) id:4 { }
        (後略)
    },
    (int) 1 => object(App\Model\Entity\User) id:1 {
        'id' => (int) 2
        'nickname' => 'nickname_2'
        'email' => 'test+2@lancers.co.jp'
        'status' => 'active'
        'created' => object(Cake\I18n\FrozenTime) id:3 { }
        'modified' => object(Cake\I18n\FrozenTime) id:4 { }
        (後略)
    },
]
```

- JSON

```json
{
  "result": true,
  "message": "Entity の配列変換テスト",
  "users": [
    {
      "id": 1,
      "nickname": "nickname_1",
      "email": "test+1@lancers.co.jp",
      "status": "active",
      "created": "2008-12-16T07:32:44",
      "modified": "2020-01-29T20:27:45"
    },
    {
      "id": 2,
      "nickname": "nickname_2",
      "email": "test+2@lancers.co.jp",
      "status": "active",
      "created": "2008-12-16T07:59:27",
      "modified": "2009-02-08T13:09:39"
    }
  ]
}
```

# 課題
- ドキュメントの PR 出すべきでは
- CI の設定追加
- IDE で気付けるように調整