Eloquent 是 Laravel 自带的 ORM(对象关系映射),让你能够使用优雅的 ActiveRecord 模式与数据库交互。 每个数据库表都对应一个「模型」,通过模型你可以轻松地查询、插入、更新和删除数据。 本章将系统讲解如何定义 Eloquent 模型,并配置其与数据库的映射关系。
模型通常位于 app/Models 目录(Laravel 11 默认位置)。每个模型对应一张数据库表,你可以在模型中定义表名、主键、可填充字段、关联关系等。
Eloquent 提供了丰富的功能,让数据库操作变得简单而强大。
使用 Artisan 命令 make:model 快速创建模型:
php artisan make:model Post
该命令会在 app/Models 目录下生成 Post.php 文件:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
// 模型相关配置
}
常用选项:
--migration 同时生成迁移文件--controller 生成对应的控制器--factory 生成模型工厂--all 生成模型、迁移、控制器、工厂、资源等全套文件Eloquent 遵循「约定优于配置」的原则,通过简单的命名规则自动推断表名、主键等。
默认情况下,模型类名的复数形式作为表名(小写+下划线)。例如 Post 模型对应 posts 表。如需自定义,设置 $table 属性:
protected $table = 'blog_posts';
默认主键是 id,且为自增整数。可通过 $primaryKey 自定义:
protected $primaryKey = 'post_id';
如果主键不是自增的,需设置 $incrementing = false;如果主键不是整数,需设置 $keyType = 'string'。
Eloquent 默认期望表中存在 created_at 和 updated_at 字段。如果不需要自动维护,设置 $timestamps = false:
public $timestamps = false;
自定义时间戳字段名:
const CREATED_AT = 'created';
const UPDATED_AT = 'updated';
默认使用 config/database.php 中的默认连接。可通过 $connection 属性指定其他连接:
protected $connection = 'mysql_secondary';
为了安全,Eloquent 默认不允许批量赋值。你需要通过 $fillable 或 $guarded 属性指定哪些字段可以被批量赋值。
protected $fillable = ['title', 'content', 'user_id'];
允许批量赋值的字段列表。
protected $guarded = ['id', 'created_at', 'updated_at'];
禁止批量赋值的字段。如果 $guarded 为空数组,表示所有字段都可批量赋值。不推荐使用 $guarded = [],除非你完全信任用户输入。
$fillable 或 $guarded,防止恶意用户修改不应该修改的字段。
通过 $casts 属性可以自动将数据库字段转换为 PHP 类型,简化数据处理:
protected $casts = [
'is_published' => 'boolean',
'price' => 'decimal:2',
'options' => 'array', // JSON 字段自动转为数组
'published_at' => 'datetime',
'metadata' => 'json',
'views' => 'integer',
];
支持的类型:integer、real、float、double、string、boolean、object、array、collection、date、datetime、timestamp、encrypted 等。
Laravel 11 还支持自定义类型转换,通过实现 Illuminate\Contracts\Database\Eloquent\CastsAttributes 接口。
Eloquent 会自动将 created_at、updated_at 以及通过 $casts 标记为 datetime 的字段转换为 Carbon 实例。可以通过 $dates 属性(Laravel 11 推荐使用 $casts)或 serializeDate 方法自定义格式:
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
Eloquent 提供了多种关联关系,让你轻松处理表间关系。以下是最常用的几种:
// User 模型
public function profile()
{
return $this->hasOne(Profile::class);
}
// Profile 模型
public function user()
{
return $this->belongsTo(User::class);
}
// Post 模型
public function comments()
{
return $this->hasMany(Comment::class);
}
// Comment 模型
public function post()
{
return $this->belongsTo(Post::class);
}
// User 模型
public function roles()
{
return $this->belongsToMany(Role::class)->withTimestamps();
}
还有 hasManyThrough、hasOneThrough、morphMany(多态关联)等高级关联,可根据业务需求使用。
作用域允许你定义通用的查询约束,提高代码复用性。
在模型中以 scope 前缀定义方法:
public function scopePublished($query)
{
return $query->where('is_published', true);
}
public function scopeOfUser($query, $userId)
{
return $query->where('user_id', $userId);
}
使用时:Post::published()->ofUser(1)->get();
用于自动为所有查询添加约束,例如软删除。可通过实现 Illuminate\Database\Eloquent\Scope 接口定义,或在模型的 booted 方法中注册:
protected static function booted()
{
static::addGlobalScope('age', function (Builder $builder) {
$builder->where('age', '>', 18);
});
}
Eloquent 模型触发多种事件,可以在模型生命周期的关键时刻执行代码。
支持的模型事件:retrieved、creating、created、updating、updated、saving、saved、deleting、deleted、restoring、restored、replicating。
可以在模型的 booted 方法中注册事件:
protected static function booted()
{
static::created(function ($user) {
Log::info("新用户注册: {$user->email}");
});
}
对于复杂的事件处理,可以使用观察者类将逻辑集中管理:
php artisan make:observer UserObserver --model=User
在 App\Providers\EventServiceProvider 中注册观察者:
use App\Models\User;
use App\Observers\UserObserver;
public function boot(): void
{
User::observe(UserObserver::class);
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
use SoftDeletes; // 软删除
protected $table = 'posts';
protected $fillable = [
'title',
'slug',
'content',
'user_id',
'is_published',
'published_at',
];
protected $casts = [
'is_published' => 'boolean',
'published_at' => 'datetime',
];
// 关联用户
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
// 关联评论
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
// 本地作用域:已发布的文章
public function scopePublished($query)
{
return $query->where('is_published', true);
}
// 事件:创建时自动生成 slug
protected static function booted()
{
static::creating(function ($post) {
$post->slug = \Str::slug($post->title);
});
}
}
$fillable 和 $casts 可以大大提高代码的安全性和可读性。
app/Models 目录。你可以自定义命名空间和目录,但需确保 composer.json 中的自动加载配置正确。
$fillable 显式列出允许的字段,更安全清晰。
$incrementing = false,并可能需要设置 $keyType = 'string'(如果主键不是整数)。
Eloquent 模型是 Laravel 数据库操作的核心,通过简单的配置即可实现复杂的业务逻辑。 熟练掌握模型定义,可以让你充分利用 Laravel 的强大功能,写出优雅、安全、可维护的代码。 下一章我们将深入学习 Eloquent 的增删改查操作,带你体验极简的数据交互。