Laravel使用first()查询数据时报Trying to get property of non-object错误如何解决
问题排查与解决
错误根因
你遇到的Trying to get property 'id_pembelian' of non-object错误,是因为Pembayaran::select('id_pembelian')->where('id',$id)->first()执行时,数据库中没有匹配id = $id的Pembayaran记录,first()方法在无匹配数据时会返回null而非对象,尝试访问null的属性就会触发该报错。
修复方案
1. 核心修复逻辑
优先补充数据存在性校验,有两种常用实现方式:
- 用Laravel自带的
firstOrFail()方法替代first(),无匹配数据时会自动抛出404异常,终止后续逻辑执行 - 手动判断
first()返回值是否为空,自定义返回错误提示
2. 额外性能优化
你当前代码对同一条Pembayaran记录发起了2次独立查询,可合并为一次查询减少数据库IO消耗,优化后的完整代码如下:
public function update(Request $request, $id) { $request->validate([ 'total_bayar' => 'required|integer' ]); // 合并查询,一次取出所需字段,无匹配数据自动抛404 $pembayaran = Pembayaran::select('total_bayar', 'id_pembelian') ->where('id', $id) ->firstOrFail(); // 同样校验关联的Pembelian记录是否存在 $harga_bayar = Pembelian::select('total_harga') ->where('id', $pembayaran->id_pembelian) ->firstOrFail(); $total_akan_terbayar = $pembayaran->total_bayar + $request->get('total_bayar'); if(($harga_bayar->total_harga != $pembayaran->total_bayar) && ($harga_bayar->total_harga > $total_akan_terbayar)){ $data = [ 'total_bayar'=> $request->get('total_bayar'), 'updated_at' => Carbon::now(), 'status' => 'cicil' ]; $isSaved = Pembayaran::where('id',$id)->update($data); if($isSaved){ return Redirect::to('/pembayaran/'.$id.'/edit')->with('warning','Transaksi Anda Sebesar Rp.'.$total_akan_terbayar.' Berhasil dicatat'); }else{ return Redirect::to('/pembayaran/'.$id.'/edit')->with('error','Transaksi Anda Gagal dicatat'); } } elseif(($harga_bayar->total_harga != $pembayaran->total_bayar) && ($harga_bayar->total_harga == $total_akan_terbayar)) { $data = [ 'total_bayar'=> $request->get('total_bayar'), 'updated_at' => Carbon::now(), 'status' => 'lunas' ]; $isSaved = Pembayaran::where('id',$id)->update($data); if($isSaved){ return Redirect::to('/pembayaran/'.$id.'/edit')->with('warning','Transaksi Anda Sebesar Rp.'.$total_akan_terbayar.' Berhasil dicatat'); }else{ return Redirect::to('/pembayaran/'.$id.'/edit')->with('error','Transaksi Anda Gagal dicatat'); } } elseif(($harga_bayar->total_harga != $pembayaran->total_bayar) && ($harga_bayar->total_harga < $total_akan_terbayar)) { return Redirect::to('/pembayaran/'.$id.'/edit')->with('warning','Jumlah yang anda masukan berlebih Rp.'.($total_akan_terbayar-$harga_bayar->total_harga)); } else { return Redirect::to('/pembayaran/'.$id.'/edit')->with('error','Transaksi Anda Gagal dicatat'); } }
其他优化提示
- Laravel的
validate方法验证失败时会自动跳转回上一页并携带错误信息,无需单独赋值$isValid判断 - 可提前配置Pembayaran和Pembelian的模型关联,后续查询可直接通过关联方法获取数据,无需手动写条件查询关联ID
内容的提问来源于stack exchange,提问作者Rido Sitanggang
相关产品推荐
相关产品推荐

