PHP
LaravelのSaveメソッドでIllegal offset typeエラーがでた
ぽんて
更新日:2022/07/07
SaveメソッドでIllegal offset typeエラーがでたので少し調査してみた
LaravelでSaveメソッドを利用したとき、Illegal offset typeエラーが発生しました!
正しく使えてるはずなのになぜ!!、ということで原因を調査。
その結果をまとめてみました。
発生状況
データベース
Modelクラス
1 2 3 4 5 6 7 8 9 |
namespace App\Models; class Hoge extends Model { protected $primaryKey = ['hoge_id','hoga_no']; public $incrementing = false; public $timestamps = false; protected $table = 'Hoge; public $fillable = ['hoge_id','hoga_no','free_text']; } |
Controllerクラス
1 2 3 4 5 6 7 8 9 10 11 12 |
namespace App\Models; use App\Models\Hoge; class HogeController extends Controller { public function index(Request $request){ $hoge_model = Hoge::firstOrNew([ 'hoge_id' => 1, 'hoge_no' => 1, ]); $hoge_model->fill(['free_text' => 'hogahoga']); $hoge_model->save(); } |
動作内容
期待する動作
Hogeテーブルのfree_textの内容が「hogahoga」に更新される
実際の動作
Illegal offset typeエラーが発生!
発生箇所、原因
以下の条件が重なると発生するみたいです
Modelクラス
primaryキーを複数指定する(複合主キー)
1 2 |
namespace App\Models; protected $primaryKey = ['hoge_id','hoga_no']; |
の行ですね。
Controllerクラス
fillしてからsaveする
1 2 3 4 |
namespace App\Models; $hoge_model->fill(['free_text' => 'hogahoga']); $hoge_model->save(); } |
の行ですね。
save単体では発生しませんでした。
ソースを追うと、save()のときに通るwhere句を組み立てる関数でエラーが発生していました!
Laravelでは複合主キーのときにfill()→save()による更新処理はできない仕様(バグ?)のようです。
対策
複合主キーのときはfill()->save()を使わない!
updateOrInsertを利用する!
サロゲートキーを使い、複合主キーになることを避ける!
そもそもLaravelは基本は単一キーを推奨している、ように見える。
であればそもそも複合主キーを使わない設計にするのもありかも
おまけ
saveメソッド以外のIllegal offset typeエラー
$primaryを複数指定した場合Modelクラスに「$incremating = false」の設定漏れでも同様のエラーが発生します。
漏れのないようにしましょう!
ぽんて