4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-11-12

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

Notice: Deprecated (16384): Setting special view var "_serialize" is deprecated.

Notice だけ抜粋します。(実際のURLなどは加工しています)

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 で記述するものとします。

修正前

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

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

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

修正後

$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 が出ますがご容赦を
// 例えば 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 表示
[
    (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
{
  "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 で気付けるように調整
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?