Search code examples
phplaraveleloquentchunking

How to terminate Eloquent chunking from closure


Using Eloquent, how can I terminate chunking based on a condition within the chunk function's closure? I've tried returning, but that seems to terminate only the current chunk and not all chunking. At this point, I want to stop retrieving records from the database.

$query->chunk(self::CHUNK_SIZE, function ($objects) {
    if (someCondition) {
        // terminate chunking here
        return;
    }
});

Solution

  • If you return false it will break. If you are in a do while loop and return anything it will exit the loop. In the source code below you can see:

            if ($callback($results) === false) {
                return false;
            }
    

    which gives you an opportunity to exit out.

     /**
         * Chunk the results of the query.
         *
         * @param  int  $count
         * @param  callable  $callback
         * @return bool
         */
        public function chunk($count, callable $callback)
        {
            $this->enforceOrderBy();
            $page = 1;
            do {
                // We'll execute the query for the given page and get the results. If there are
                // no results we can just break and return from here. When there are results
                // we will call the callback with the current chunk of these results here.
                $results = $this->forPage($page, $count)->get();
                $countResults = $results->count();
                if ($countResults == 0) {
                    break;
                }
                // On each chunk result set, we will pass them to the callback and then let the
                // developer take care of everything within the callback, which allows us to
                // keep the memory low for spinning through large result sets for working.
                if ($callback($results) === false) {
                    return false;
                }
                $page++;
            } while ($countResults == $count);
            return true;
        }
    

    https://github.com/laravel/framework/blob/5.4/src/Illuminate/Database/Concerns/BuildsQueries.php#L18