web-dev-qa-db-ja.com

Eloquentは10進数を文字列としてキャストします

Eloquentモデルでお金を表す10進数フィールドがあり、このフィールドに数値を追加しようとすると、誤った結果に気づきます。

さらに調べたところ、10進数フィールドは、ティンカーコンソールの_"1245114.00"_のように、文字列としてキャストされていることがわかりました。

テーブル構造を確認したところ、フィールドが実際にdecimal(11,3)であることを確認できました。

この質問は 前に尋ねた でしたが、答えはありません。

なんでこんなことが起こっているの?

8
Sapnesh Naik

モデルで、プリミティブ属性にキャストする必要があるフィールドを定義する必要があります。

protected $casts = [
    'my_decimal' => 'float',
];

モデルの$castsプロパティは、属性を一般的なデータ型に変換する便利な方法を提供します。 $castsプロパティは、キーがキャストされる属性の名前であり、値が列のキャスト先の型である配列である必要があります。サポートされているキャストタイプは、integerrealfloatdoublestringbooleanobjectarraycollectiondatedatetimetimestamp

ここに本当に良い説明があります:

https://mattstauffer.com/blog/laravel-5.0-eloquent-attribute-casting/

また、ドキュメントに説明があります:

https://laravel.com/docs/5.5/eloquent-mutators#attribute-casting

Laravelのgithubリポジトリのこのスレッドによると: https://github.com/laravel/framework/issues/1178

PDOドライバーの問題のようです。小数を文字列に自動的にキャストします。そのスレッドの人々は、それはmysql 5.2ドライバーの問題であり、一部は5.1にロールバックされたと述べました。自分のサーバーを使用している場合は、ダウングレードできます。それ以外の場合は、モデルレベルでフロートするようにキャストする必要があります。

7
Niels

Laravelモデルではデータベースの10進数の列が文字列として表示されるため、この問題の分析に少し時間を費やしました。

重要なことは、モデルのフロートに型キャストを追加することですdoes修正しますが、私のような場合、dd(\App\SomeModel::someScope()->get());に型キャストを追加した後でも、これらの10進数列が文字列として表示されることに気付きましたモデル。

これらの値がクライアントに送信されるとき、それらは整数であるため、型キャストによって元の問題が修正され、JavaScriptがNumberではなくStringを受信できるようになりました。

dd()の出力に焦点を当てているために時間を無駄にしないように、私はこの答えを出しています。私はPDOドライバーについての解決策を調査しましたが、いくつかにはメリットがあるかもしれませんが、実際のデータベース出力が正しいタイプにキャストされるので、それは大した問題ではありません。

2
agm1984

PHPには小数型がないため、このようにする必要があります。小数を浮動小数点にキャストすると、精度が低下する可能性があります。

最良のオプションは、文字列のままにすることです。次に、bcmathを使用して操作します。これは、文字列で使用するためのものです。

0
dRamentol