Eloquentモデルでお金を表す10進数フィールドがあり、このフィールドに数値を追加しようとすると、誤った結果に気づきます。
さらに調べたところ、10進数フィールドは、ティンカーコンソールの_"1245114.00"
_のように、文字列としてキャストされていることがわかりました。
テーブル構造を確認したところ、フィールドが実際にdecimal(11,3)
であることを確認できました。
この質問は 前に尋ねた でしたが、答えはありません。
なんでこんなことが起こっているの?
モデルで、プリミティブ属性にキャストする必要があるフィールドを定義する必要があります。
protected $casts = [
'my_decimal' => 'float',
];
モデルの
$casts
プロパティは、属性を一般的なデータ型に変換する便利な方法を提供します。$casts
プロパティは、キーがキャストされる属性の名前であり、値が列のキャスト先の型である配列である必要があります。サポートされているキャストタイプは、integer
、real
、float
、double
、string
、boolean
、object
、array
、collection
、date
、datetime
、timestamp
ここに本当に良い説明があります:
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にロールバックされたと述べました。自分のサーバーを使用している場合は、ダウングレードできます。それ以外の場合は、モデルレベルでフロートするようにキャストする必要があります。
Laravelモデルではデータベースの10進数の列が文字列として表示されるため、この問題の分析に少し時間を費やしました。
重要なことは、モデルのフロートに型キャストを追加することですdoes修正しますが、私のような場合、dd(\App\SomeModel::someScope()->get());
に型キャストを追加した後でも、これらの10進数列が文字列として表示されることに気付きましたモデル。
これらの値がクライアントに送信されるとき、それらは整数であるため、型キャストによって元の問題が修正され、JavaScriptがNumber
ではなくString
を受信できるようになりました。
dd()
の出力に焦点を当てているために時間を無駄にしないように、私はこの答えを出しています。私はPDOドライバーについての解決策を調査しましたが、いくつかにはメリットがあるかもしれませんが、実際のデータベース出力が正しいタイプにキャストされるので、それは大した問題ではありません。
PHPには小数型がないため、このようにする必要があります。小数を浮動小数点にキャストすると、精度が低下する可能性があります。
最良のオプションは、文字列のままにすることです。次に、bcmathを使用して操作します。これは、文字列で使用するためのものです。