วิธีใช้ Laravel Collection ใน Cronjob สำหรับ Process ข้อมูล

วิธีใช้ Laravel Collection ใน Cronjob สำหรับ Process ข้อมูล

หากคุณเคยเขียน Laravel Cronjob และต้องมานั่งเขียน loop ซ้ำๆ เพื่อ process ข้อมูล บทความนี้จะแนะนำวิธีใช้ Laravel Collection ร่วมกับ Cronjob ที่จะทำให้โค้ดของคุณสะอาดและอ่านง่ายขึ้นมาก


ทำไมต้องใช้ Laravel Collection ใน Cronjob?

ในการเขียน scheduled task หรือ cronjob สิ่งที่เราทำบ่อยๆ คือ:

  • ดึงข้อมูลจาก database
  • กรองข้อมูลบางส่วน
  • คำนวณค่าต่างๆ
  • สร้าง report

ถ้าเขียนแบบเดิมๆ เราจะต้องเขียน foreach หลายชั้น ทำให้โค้ดยาวและอ่านยาก แต่ถ้าใช้ Laravel Collection เราสามารถ chain methods ได้เลย ทำให้โค้ดกระชับและเข้าใจง่าย

// แบบเดิม - ยาวและอ่านยาก
$orders = Order::whereDate('created_at', today())->get();
$completed = [];
foreach ($orders as $order) {
    if ($order->status === 'completed') {
        $completed[] = $order;
    }
}
$total = 0;
foreach ($completed as $order) {
    $total += $order->amount;
}

// แบบ Collection - กระชับ
$total = Order::whereDate('created_at', today())
    ->get()
    ->filter(fn($o) => $o->status === 'completed')
    ->sum('amount');

พื้นฐาน Laravel Collection สำหรับ Cronjob

สร้าง Collection จาก Model

// ดึงข้อมูลมาเป็น Collection
$orders = Order::whereDate('created_at', today())->get();

// หรือสร้างจาก array
$collection = collect($data);

Method ที่ใช้บ่อยใน Cronjob

Method การใช้งาน
filter() กรองข้อมูลตามเงื่อนไข
map() แปลงข้อมูลแต่ละ item
groupBy() จัดกลุ่มข้อมูล
pluck() ดึงค่าเฉพาะ field
sum(), avg(), count() คำนวณค่าต่างๆ
first(), last() ดึง item แรก/สุดท้าย

ตัวอย่างการใช้งานจริง: Daily Sales Report

สมมติว่าเราต้องการสร้างรายงานยอดขายประจำวัน โดย:

  1. ดึง orders ของวันนี้
  2. จัดกลุ่มตาม status
  3. คำนวณยอดรวมแต่ละ status
  4. ส่ง email รายงาน

ขั้นตอนที่ 1 – ดึงข้อมูล

$orders = Order::whereDate('created_at', today())->get();

ขั้นตอนที่ 2 – Process ด้วย Collection

$report = $orders
    ->groupBy('status')
    ->map(function ($group, $status) {
        return [
            'status' => $status,
            'count' => $group->count(),
            'total_amount' => $group->sum('amount'),
            'avg_amount' => $group->avg('amount'),
        ];
    })
    ->values(); // reset keys

ผลลัพธ์จะเป็น:

[
    ['status' => 'completed', 'count' => 150, 'total_amount' => 150000, 'avg_amount' => 1000],
    ['status' => 'pending', 'count' => 30, 'total_amount' => 25000, 'avg_amount' => 833],
    ['status' => 'cancelled', 'count' => 5, 'total_amount' => 2000, 'avg_amount' => 400],
]

ขั้นตอนที่ 3 – ส่ง Report

$message = $report->map(fn($r) => "- {$r['status']}: {$r['count']} orders, ฿{$r['total_amount']}")->join("\n");

Mail::to('[email protected]')->send(new DailyReport($message));

ใส่ใน Cronjob

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->dailyAt('08:00')->call(function () {
        $orders = Order::whereDate('created_at', today())->get();

        $report = $orders
            ->groupBy('status')
            ->map(fn($group, $status) => [
                'status' => $status,
                'count' => $group->count(),
                'total_amount' => $group->sum('amount'),
            ])
            ->values();

        Mail::to('[email protected]')->send(new DailyReport($report));
    });
}

เทคนิคสำหรับข้อมูลขนาดใหญ่

ถ้าต้อง process ข้อมูลหลายแสน record ใน cronjob ต้องระวังเรื่อง memory usage

ใช้ chunk() แทน all()

// ❌ ดึงทั้งหมดมาพร้อมกัน - กิน memory
$orders = Order::all();

// ✅ แบ่งทีละ 100 records - ประหยัด memory
Order::where('processed', false)->chunk(100, function ($records) {
    foreach ($records as $record) {
        // process each record
    }
});

ใช้ cursor() สำหรับ Memory Efficiency

// ใช้ cursor() สำหรับ iterate โดยไม่ต้องโหลดทั้งหมด
$total = 0;
foreach (Order::where('processed', false)->cursor() as $order) {
    $total += $order->amount;
    // process...
}

ใช้ lazy Collection

// lazy() จะไม่โหลดข้อมูลทั้งหมดมาก่อน
$collection = Model::where('status', 'active')->lazy()
    ->filter(fn($m) => $m->isValid())
    ->take(100);

สรุป

การใช้ Laravel Collection ใน Cronjob ช่วยให้:

  • โค้ดสั้นลง – เขียน less, do more
  • อ่านง่าย – chain methods ตามลำดับการทำงาน
  • แก้ไขง่าย – เพิ่ม/ลด logic โดยไม่ต้องแก้ loop
  • Test ได้ง่าย – Collection methods มี built-in testing helpers

ลองนำไปประยุกต์ใช้กับ cronjob ของคุณดูนะครับ 🚀

เกี่ยวกับผู้เขียน

ITTHIPAT

สวัสดีครับผม อิทธิพัทธ์ (เป้) ชอบหาเทคนิคต่างๆที่ทำให้ชีวิต Programmer ง่ายขึ้น ทั้ง Automate, Library ชอบทำ Blog และ Video ถ้ามีเวลานะ!

ขอบคุณทุกคนที่ติดตาม และอ่านบทความของผมครับ ผมหวังว่าความรู้ที่เขียนขึ้นในเว็บไซต์นี้จะช่วยทุกท่านได้ไม่มากก็น้อย 

Scroll to Top