
Eloquent ORM 看似简单,但在底层却隐藏着许多不为人知的技巧和功能。这篇文章将带你了解一些实用的小窍门。
代替传统方式:
$article = Article::find($article_id); $article->read_count++; $article->save();
可以使用更简洁的方法:
$article = Article::find($article_id);
$article->increment('read_count');更多用法示例:
Article::find($article_id)->increment('read_count');
Article::find($article_id)->increment('read_count', 10); // 增加10
Product::find($produce_id)->decrement('stock'); // 减少1Eloquent 提供了一些便捷方法来简化操作流程。
实例 1:findOrFail()
代替:
$user = User::find($id);
if (!$user) {
abort(404);
}直接写为:
$user = User::findOrFail($id);
实例 2:firstOrCreate()
代替:
$user = User::where('email', $email)->first();
if (!$user) {
User::create([
'email' => $email
]);
}可以写成:
$user = User::firstOrCreate(['email' => $email]);
在模型中使用 boot() 可以修改默认行为,例如监听事件。
class User extends Model
{
public static function boot()
{
parent::boot();
static::updating(function ($model) {
// 可以在这里记录日志或修改字段值
});
}
}创建时自动设置 UUID 示例:
public static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->uuid = (string)Uuid::generate();
});
}普通关联定义:
public function users()
{
return $this->hasMany('App\User');
}也可以添加查询条件和排序:
public function approvedUsers()
{
return $this->hasMany('App\User')->where('approved', 1)->orderBy('email');
}常见模型属性设置如下:
class User extends Model
{
protected $table = 'users';
protected $fillable = ['email', 'password'];
protected $dates = ['created_at', 'deleted_at'];
protected $appends = ['field1', 'field2'];
}其他可配置项包括:
protected $primaryKey = 'uuid'; // 自定义主键 public $incrementing = false; // 关闭自增 protected $perPage = 25; // 分页数量 const CREATED_AT = 'created_at'; const UPDATED_AT = 'updated_at'; // 自定义时间戳字段 public $timestamps = false; // 关闭时间戳
find() 不仅支持单个 ID 查询,还支持数组传参:
$users = User::find([1, 2, 3]);
可以将以下代码:
$users = User::where('approved', 1)->get();改写为:
$users = User::whereApproved(1)->get();
也支持时间相关查询:
User::whereDate('created_at', date('Y-m-d'));
User::whereDay('created_at', date('d'));
User::whereMonth('created_at', date('m'));
User::whereYear('created_at', date('Y'));假设我们想根据主题最新帖子进行排序:
定义关联:
public function latestPost()
{
return $this->hasOne(\App\Post::class)->latest();
}控制器中使用:
$users = Topic::with('latestPost')->get()->sortByDesc('latestPost.created_at');替代传统的 if-else 写法:
if (request('filter_by') == 'likes') {
$query->where('likes', '>', request('likes_amount', 0));
}
if (request('filter_by') == 'date') {
$query->orderBy('created_at', request('ordering_rule', 'desc'));
}使用 when() 更优雅:
$query = Author::query();
$query->when(request('filter_by') == 'likes', function ($q) {
return $q->where('likes', '>', request('likes_amount', 0));
});
$query->when(request('filter_by') == 'date', function ($q) {
return $q->orderBy('created_at', request('ordering_rule', 'desc'));
});避免访问不存在的关系对象导致错误:
原写法可能报错:
{{ $post->author->name }}优化为返回默认模型:
public function author()
{
return $this->belongsTo('App\Author')->withDefault();
}还可以指定默认值:
public function author()
{
return $this->belongsTo('App\Author')->withDefault([
'name' => 'Guest Author'
]);
}当使用访问器排序时,不能直接使用 orderBy():
$clients = Client::orderBy('full_name')->get(); // 无效应改为:
$clients = Client::get()->sortBy('full_name'); // 有效注意使用的是 sortBy() 而不是 orderBy()。
在 boot() 中设置全局作用域实现默认排序:
protected static function boot()
{
parent::boot();
<pre class="brush:php;toolbar:false;"><code>static::addGlobalScope('order', function (Builder $builder) {
$builder->orderBy('name', 'asc');
});}
Eloquent 支持嵌入原生 SQL 查询:
// whereRaw
$orders = DB::table('orders')
->whereRaw('price > IF(state = "TX", ?, 100)', [200])
->get();</p><p>// havingRaw
Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();</p><p>// orderByRaw
User::where('created_at', '>', '2016-01-01')
->orderByRaw('(updated_at - created_at) desc')
->get();使用 replicate() 快速复制数据:
$task = Tasks::find(1); $newTask = $task->replicate(); $newTask->save();
代替一次性加载全部数据:
$users = User::all();
foreach ($users as $user) {
// ...
}使用 chunk() 分批处理:
User::chunk(100, function ($users) {
foreach ($users as $user) {
// ...
}
});Artisan 命令:
php artisan make:model Company -mcr
参数说明:
-m 生成迁移文件-c 生成控制器-r 生成资源控制器可以通过参数阻止自动更新时间戳:
$product = Product::find($id); $product->updated_at = '2019-01-01 10:00:00'; $product->save(['timestamps' => false]);
update() 方法会返回数据库中受影响的行数:
$result = $products->whereNull('category_id')->update(['category_id' => 2]);此时 $result 就是被更新的数据条数。
SQL 查询:
WHERE (gender = 'Male' AND age >= 18) OR (gender = 'Female' AND age >= 65)
对应 Eloquent 写法:
$q->where(function ($query) {
$query->where('gender', 'Male')->where('age', '>=', 18);
})->orWhere(function ($query) {
$query->where('gender', '以上就是20 个 Laravel Eloquent 必备的实用技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号