Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

tahertechs's avatar

How to Paginate Available Collection.

Suppose I have 200 records in my DB. While displaying those records I want to paginate them. The normal approach would be something like $tasks = Tasks::paginate(10); Then $tasks->links();. That code works fine. However, With that code you gonna run DB query every time you fetch 10rows (200/10=20times).

What I need is to fetch all data at once, store them in a collection (say $tasks),Then paginate the resulting collection instead of fetching again from DB.

Even more, I need to query something like "Get only 100 records and paginate them by 10 " which would be nice if it would be something like Tasks::take(100)->paginate(10) but unfortunately that even do not work.

Anyone with an idea on how to tackle these issues?

0 likes
7 replies
iskubiy's avatar

Get your collection from db. All 200 records. Then create an instance of Paginator class. (for laravel 5) Like this :

$paginator = new Paginator($items->forPage($page,$per_page),$items->count(),$per_page,$page);

where $items is your collection

2 likes
tahertechs's avatar

Am using L4.2 , I tried this way, $tutorials = Tutorial::all(); then returning $tutorials = Paginator::make($tutorials, count($tutorials), 10); but get Argument 1 passed to Illuminate\Pagination\Factory::make() must be of the type array, object given, error.

jekinney's avatar

Eager load the links table.

Task::with('links')->paginate(10);

Now it will load all the related links in two queries versus one for each task.

azimidev's avatar

Create a helper function like this:

function paginate($items, $perPage)
{
    $pageStart           = request('page', 1);
    $offSet              = ($pageStart * $perPage) - $perPage;
    $itemsForCurrentPage = array_slice($items, $offSet, $perPage, TRUE);

    return new Illuminate\Pagination\LengthAwarePaginator(
        $itemsForCurrentPage, count($items), $perPage,
        Illuminate\Pagination\Paginator::resolveCurrentPage(),
        ['path' => Illuminate\Pagination\Paginator::resolveCurrentPath()]
    );
}

If you want to use collections instead of arrays use this:

function paginate($items, $perPage)
{
    $pageStart = request('page', 1);
    $offSet    = ($pageStart * $perPage) - $perPage;
    $itemsForCurrentPage = $items->slice($offSet, $perPage);

    return new Illuminate\Pagination\LengthAwarePaginator(
        $itemsForCurrentPage, $items->count(), $perPage,
        Illuminate\Pagination\Paginator::resolveCurrentPage(),
        ['path' => Illuminate\Pagination\Paginator::resolveCurrentPath()]
    );
}
6 likes
jlrdw's avatar

Pagination a collection is not a good idea, that's why there is pagination, don't be so coy. Just saw old post, but wondering how a collection of 500,000 records would work for our OP, a good grief moment. The more reason to know basics before delving deep into laravel.

taekunger's avatar

An edit for the previous paginator function to make use of the Illuminate\Pagination\LengthAwarePaginator class, it works perfect for me specially for ajax calls

/**
 * Paginate a laravel colletion or array of items.
 *
 * @param  array|Illuminate\Support\Collection $items   array to paginate
 * @param  int $perPage number of pages
 * @return Illuminate\Pagination\LengthAwarePaginator    new LengthAwarePaginator instance 
 */
function paginate($items, $perPage)
{
    if(is_array($items)){
        $items = collect($items);
    }

    return new Illuminate\Pagination\LengthAwarePaginator(
        $items->forPage(Illuminate\Pagination\Paginator::resolveCurrentPage() , $perPage),
        $items->count(), $perPage,
        Illuminate\Pagination\Paginator::resolveCurrentPage(),
        ['path' => Illuminate\Pagination\Paginator::resolveCurrentPath()]
    );
}

6 likes

Please or to participate in this conversation.