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

Laravel Carbon查询本月数据返回0结果,如何解决?

解决Laravel中获取用户本月数据的问题

你的问题主要出在两个关键点上:一是你在内存集合层面做筛选,而非数据库查询层面;二是日期比较的类型匹配可能出了问题。

正确解决方案

你需要调用$user->products()(这是Query Builder实例)来添加查询条件,让筛选逻辑在数据库层面执行,既高效又能避免类型问题。这里提供几种可靠的写法:

方法1:用时间范围精准限定本月(推荐)

利用Carbon的startOfMonth()和endOfMonth()直接划定本月的时间区间:

dd($user->products()
    ->where('paid', 1)
    ->whereBetween('created_at', [
        Carbon::now()->startOfMonth(),
        Carbon::now()->endOfMonth()
    ])
    ->get());

方法2:单独匹配年份和月份

通过whereYear和whereMonth精准定位当前月份:

dd($user->products()
    ->where('paid', 1)
    ->whereYear('created_at', Carbon::now()->year)
    ->whereMonth('created_at', Carbon::now()->month)
    ->get());

方法3:基于日期字符串筛选

如果只需要匹配日期部分,可以用whereDate:

dd($user->products()
    ->where('paid', 1)
    ->whereDate('created_at', '>=', Carbon::now()->startOfMonth()->toDateString())
    ->get());

原代码返回0条结果的原因

  1. 集合筛选的低效与类型问题:你写的$user->products会先把该用户所有产品加载到内存的Collection中,再用Collection的where方法筛选。这种方式不仅效率极低(数据量大时尤为明显),而且当created_at是Carbon实例时,和toDateString()返回的字符串日期比较,可能因类型不匹配导致筛选失效。
  2. 日期比较的类型不兼容:Carbon::now()->startOfMonth()原本是带时间的Carbon对象(比如2024-05-01 00:00:00),你转成字符串后变成2024-05-01,集合中的created_at是Carbon对象,两者比较时无法自动完成类型转换,最终导致条件不成立。

而你用Carbon::now()->subMonth()能获取数据,是因为subMonth()返回的是Carbon对象,和集合中的Carbon类型created_at匹配,所以筛选有效,但这并不是你需要的“本月数据”范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:29:33