Collections lazily, with chunk and cursor

Model::all() on a table with four hundred thousand rows hydrates four hundred thousand objects and then the process dies, having done nothing.

// loads everything. do not.
$this->export(Order::all());

// 1,000 rows at a time, 1,000 objects at a time
Order::where('exported', false)->chunkById(1000, function ($orders) {
    foreach ($orders as $order) {
        $this->export($order);
    }
});

// one row at a time, one object at a time
foreach (Order::where('exported', false)->cursor() as $order) {
    $this->export($order);
}

chunkById rather than chunk is the important detail when the loop modifies the rows it is iterating: plain chunk uses an offset, and updating a row so it no longer matches the where clause shifts everything and silently skips records. cursor keeps one model in memory but holds the result set open on the connection for the duration, which matters if the body is slow.