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 5 years have passed since last update.

Eloquentから取得したint型データがstring型になる

Last updated at Posted at 2019-08-08

経緯

LaravelでAPIサーバを開発中です。AWSのcodebuildでテストを走らせるためにテストのDBをMariaDBからSQLite3に変更しました。すると今まで通ってたテストが...失敗する...

Eloquentから取得したデータをJSON形式に整形して付き合わせしてるテストがことごとく失敗しています。どうやらint型が勝手にString型に変換されて返ってきてるようです。

現象

テストコード


// HogeModelのデータをHogeService経由で取得する場合のテストコード
public function testHoge()
{
    $service = app(HogeService::class);
    $ret = $service->getHogeData(1);
    $ret = json_encode($ret, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
    $expected = trim(file_get_contents(__DIR__ . '/expect_05.json'));
    $this->assertEquals($expected, $ret);
}

テスト結果のactual/expecteのDiff


@@ @@ 
     "hoges": [\n 
         {\n 
             "id": 1,\n 
-            "other_id": 1,\n 
+            "other_id": "1",\n 
             "label": "yes",\n 

対応

調査1

記事の通り手元の環境でJSON_NUMERIC_CHECK オプションをつけて実行してもやはりテストが完全に通らず。なおったりなおらなかったりってフワッとしてますね。

調査2

下記は、MariaDBでこういう現象が発生しなかったのはなぜだろうと調べて行き着いた記事です。

手元の環境で確認したところ

  • mysqlndが入っている
  • PDO::ATTR_EMULATE_PREPAREStrue

ですので、mysql_pdoで自動型変換が抑制されていたようです。

対応策

DBによらず返す型は統一したいと考え、型キャストすることにしました。Laravelの$castsプロパティを使ってHogeModelに下記コードを追加しました。


protected $casts = [
    'id'       => 'int',
    'other_id' => 'int',
];

テスト通った!

まとめ

LaravelはほんとCoolだけど、PHPはまだちょっと好きになるには時間がかかりそう(オブラート)。少なくとも初心者がやるなら少なくともPHP以外をオススメするなあ...

4
2
1

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?