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 で気付けるように調整