You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 5.5:如何为所有带时间戳模型创建全局查询作用域

刚好我之前也解决过类似的问题,Laravel里实现全局查询构造器方法有两种常用方案,都能帮你摆脱重复粘贴代码的冗余问题,咱们一步步来看:

方案一:自定义查询构造器基类

这种方法适合你需要统一管理多个全局查询方法,或者后续要扩展更多相关功能的场景,核心思路是让所有模型共用一个自定义的查询构造器:

  1. 创建自定义查询构造器类
    在App\Builders目录下新建BaseQueryBuilder.php(如果没有Builders目录就自己创建),继承Laravel的基础查询构造器,然后添加你需要的全局方法:
<?php

namespace App\Builders;

use Illuminate\Database\Eloquent\Builder;

class BaseQueryBuilder extends Builder
{
    // 获取今日数据,默认使用created_at字段,可传参指定其他字段
    public function today($column = 'created_at')
    {
        return $this->whereDate($column, today());
    }

    // 获取昨日数据,同样支持自定义字段
    public function yesterday($column = 'created_at')
    {
        return $this->whereDate($column, yesterday());
    }
}
  1. 创建基础模型类
    在App\Models目录下新建BaseModel.php,让它继承Laravel的Model,然后重写newEloquentBuilder方法,返回咱们刚才自定义的查询构造器:
<?php

namespace App\Models;

use App\Builders\BaseQueryBuilder;
use Illuminate\Database\Eloquent\Model;

class BaseModel extends Model
{
    /**
     * 替换默认的查询构造器为自定义版本
     */
    public function newEloquentBuilder($query)
    {
        return new BaseQueryBuilder($query);
    }
}
  1. 让业务模型继承基础模型
    以后你所有需要使用这些全局方法的模型,都继承BaseModel而不是直接继承Model就行:
<?php

namespace App\Models;

// 这里继承BaseModel
class Post extends BaseModel
{
    // 你的模型代码...
}

使用方式
现在不管哪个模型,都能直接调用这些方法:

// 获取今日创建的文章
$todayPosts = Post::today()->get();

// 获取昨日更新的用户
$yesterdayUpdatedUsers = User::yesterday('updated_at')->get();
方案二:使用查询构造器宏(更轻量)

如果不想修改模型的继承关系,这种方法更适合你——直接给Laravel的查询构造器“打补丁”,注册全局宏:

  1. 在服务提供者里注册宏
    打开App\Providers\AppServiceProvider.php,在boot方法里添加宏定义:
<?php

namespace App\Providers;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // 注册today宏
        Builder::macro('today', function ($column = 'created_at') {
            return $this->whereDate($column, today());
        });

        // 注册yesterday宏
        Builder::macro('yesterday', function ($column = 'created_at') {
            return $this->whereDate($column, yesterday());
        });
    }

    // ... 其他代码
}

使用方式
注册完成后,所有Eloquent模型(包括关联查询)都能直接用这些方法,完全不需要改模型代码:

// 获取今日的订单
$todayOrders = Order::today()->get();

// 获取某篇文章昨日的评论
$yesterdayComments = Post::find(123)->comments()->yesterday()->get();
两种方案对比
  • 方案一(基类):适合需要集中管理大量全局查询方法,或者后续要给查询构造器添加更多复杂逻辑的场景,结构更清晰。
  • 方案二(宏):轻量快捷,不需要修改模型继承,适合快速添加少量全局方法的场景。

两种方案都能完美解决你代码冗余的问题,根据自己的需求选就行~

内容的提问来源于stack exchange,提问作者norr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:41:52