$monthlyInvoices 变量有问题吗?

Is there a problem with the $monthlyInvoices variable?

这是我的工作。 当我 运行 这项工作时,在线发票查询不显示任何内容,但有趣的是,当我交换 $onlineInvoices$offlineInvoices 变量的位置时, $onlineInvoices 查询有效,而 $offlineInvoices 无效。 当我在 $offline_sales 变量下再次重新定义 $monthlyInvoices 时它工作正常,但我想知道为什么会这样。

<?php

namespace App\Jobs;

use App\Models\Invoice;
use App\Models\InvoiceMonthlyStatistics;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class InvoiceMonthlyStatisticsJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $period = CarbonPeriod::create('2021-08-18', '1 month', Carbon::now()->toDateString());
        foreach ($period as $date) {
            $monthlyInvoices = Invoice::
            whereRaw('YEAR(created_at) = ?', $date->format('Y'))
                ->whereRaw('MONTH(created_at) = ?', $date->format('m'));

            $total_sales = $monthlyInvoices
                ->sum('net_price');


            $offline_sales = $monthlyInvoices
                ->where('type', '=', 'offline')
                ->sum('net_price');

        
            $online_sales = $monthlyInvoices
                ->where('type', '=', 'online')
                ->sum('net_price');


            $invoiceStats = (new InvoiceMonthlyStatistics)->create([
                'total_sales' => $total_sales,
                'online_sales' => $online_sales,
                'offline_sales' => $offline_sales,
                'month' => $date->format('m'),
                'year' => $date->format('y')
            ]);
        }
        $invoiceStats->save();
    }
}

这是因为 $monthlyInvoices 是一个查询生成器。

当您添加 where 语句时,即使在您调用 sum:

之后它仍然存在
$offline_sales = $monthlyInvoices
                ->where('type', '=', 'offline') //here
                ->sum('net_price');

这就是问题所在,因为当您这样做时:

$online_sales = $monthlyInvoices
                ->where('type', '=', 'online')
                ->sum('net_price');

->where('type', '=', 'offline') 还在这里,因为你之前添加了它。

从某种意义上说,您的第二个查询与以下操作相同:

$online_sales = $monthlyInvoices
                ->where('type', '=', 'offline')
                ->where('type', '=', 'online')
                ->sum('net_price');

现在你可能看到这里的问题了。解决此问题的一种快速方法是在每个查询之前克隆查询构建器。

$offline_sales = (clone $monthlyInvoices)
                ->where('type', '=', 'offline')
                ->sum('net_price');

        
$online_sales = (clone $monthlyInvoices)
                ->where('type', '=', 'online')
                ->sum('net_price');

通过克隆 $monthlyInvoices,您基本上是在说“不要使用相同的查询生成器,而是使用一个完全相同的新查询生成器”。此临时查询生成器将仅用于此特定查询,并且 where('type', '=', 'offline')(或您所做的任何操作)不会“保留”到原始 $monthlyInvoices 查询生成器中。