Laravel 5.5 预加载报错:Trying to get property of non-object
Fixing "Trying to get property of non-object" in Laravel Eager Loading
我之前跟你一模一样,在Laravel里用预加载(eager loading)的时候踩了这个坑——突然抛出Trying to get property of non-object的错误,翻了好多相关解答都没解决,最后终于揪出了问题根源!
问题场景
当我们尝试预加载模型关联(比如Book::with('author')->get()),然后访问关联模型的属性时,突然报错说“试图获取非对象的属性”,这通常是因为关联查询返回了null,但我们还是像访问对象一样去调用它的属性。
核心解决方案
在你的关联模型(比如Author和Book)里添加一行代码:
public $incrementing = false;
为什么这能解决问题?
Laravel默认假设模型的主键是自增整数类型,如果你的主键用的是UUID、字符串或者其他非自增类型,Laravel会在底层把主键当作整数处理,导致关联查询时主键匹配失败,最终返回的关联模型是null,这时候访问$book->author->name就会触发那个错误。
加上$incrementing = false后,Laravel就不会再把主键当作自增整数处理,配合指定$keyType(比如主键是字符串的话加protected $keyType = 'string';),就能让关联查询正确匹配主键,返回正常的模型对象。
我的完整代码示例
迁移文件:create_authors_table
Schema::create('authors', function (Blueprint $table) { $table->uuid('id')->primary(); // 使用UUID作为主键 $table->string('name'); $table->timestamps(); });
迁移文件:create_books_table
Schema::create('books', function (Blueprint $table) { $table->uuid('id')->primary(); $table->uuid('author_id'); $table->string('title'); $table->timestamps(); $table->foreign('author_id')->references('id')->on('authors'); });
模型:Models/Author.php
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Author extends Model { // 关键配置:关闭自增主键 public $incrementing = false; // 指定主键类型为字符串 protected $keyType = 'string'; // 关联关系:一个作者有多本书 public function books() { return $this->hasMany(Book::class); } }
模型:Models/Book.php
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Book extends Model { public $incrementing = false; protected $keyType = 'string'; // 关联关系:一本书属于一个作者 public function author() { return $this->belongsTo(Author::class); } }
路由文件:routes/web.php
use App\Models\Book; Route::get('/books', function () { // 预加载author关联 $books = Book::with('author')->get(); foreach ($books as $book) { // 现在可以正常访问关联属性了 echo $book->author->name; } });
额外提醒
如果你的模型主键确实是自增整数,那这个方案可能不适用,这时候要检查关联关系的外键是否正确,或者数据库里是否存在对应的关联数据。但如果是用非自增主键的场景,这个配置绝对是关键!
内容的提问来源于stack exchange,提问作者Kearney Taaffe
相关产品推荐
相关产品推荐

