Skip to content

Instantly share code, notes, and snippets.

@vluzrmos
Created July 20, 2016 14:31
Show Gist options
  • Save vluzrmos/3ce756322702331fdf2bf414fea27bcb to your computer and use it in GitHub Desktop.
Save vluzrmos/3ce756322702331fdf2bf414fea27bcb to your computer and use it in GitHub Desktop.
Laravel Paginate Collection or Array
<?php
/**
* Gera a paginação dos itens de um array ou collection.
*
* @param array|Collection $items
* @param int $perPage
* @param int $page
* @param array $options
*
* @return LengthAwarePaginator
*/
public function paginate($items, $perPage = 15, $page = null, $options = [])
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
}
@twizzlerz04
Copy link

Thanks for this :)

@gitipasand
Copy link

how to use this solution in ajax

@freelance-github
Copy link

I solve it

collect( [ 2 => 'Some value', 5 => 'other value' ] )->paginate(15)

https://gist.github.com/freelance-github/fe8488ff19b1a7ed67223b15c7a25b52

@moin786
Copy link

moin786 commented Dec 17, 2019

@vluzrmos great work man

@thiagolinoz
Copy link

🤯 wow.
thanks, this helped a lot

@ruffcoins
Copy link

I'm lost. Please how do i use this?

@tom1slick
Copy link

I'm lost. Please how do i use this?

Maybe this example will help you

//Getting current request link
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

//Using function on the array
$paginated_list = $this->paginate($array_to_paginate, 20, request('page'), ['path' => $actual_link, ]);

@kapitannwel
Copy link

kapitannwel commented Aug 2, 2020

$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => 'page',
]);

this is exactly what i am searching for @PaulAguirre . thank you for your contribution. stay safe!

@mohamed-nasr-ali
Copy link

awesome

@ghareebmoh
Copy link

For those who has issues with second page:

where 2nd page data has keys like:

"data": {
    "5": {
    "userId": "564110eadcb39832268ea873",
    "email": "dsdfgdfg@il.com",
    "isActive": true,
    "firstName": "dsdfgdfg",
    "lastName": "dsdfgdfg",
    "permissionType": "dsdfgdfg"
    },
    "6": {
    "userId": "564110ea2169bc358a3b65c2",
    "email": "dsdfgdfg@d.com",
    "isActive": false,
    "firstName": "dsdfgdfg",
    "lastName": "dsdfgdfg",
    "permissionType": "dsdfgdfg"
    },
    "7": {
    "userId": "564110eaee662f30c4bd6772",
    "email": "dsdfgdfg@dsdfgdfg.com",
    "isActive": true,
    "firstName": "dsdfgdfg",
    "lastName": "dsdfgdfg",
    "permissionType": "dsdfgdfg"
    },
}

This is because forPage() returns an array with keys

Fix is to add array_values():

  public function paginateCollection($items, $perPage = 15, $page = null, $options = [])
    {
        $page = $page ?: (\Illuminate\Pagination\Paginator::resolveCurrentPage() ?: 1);
        $items = $items instanceof \Illuminate\Support\Collection ? $items : \Illuminate\Support\Collection::make($items);
        return new \Illuminate\Pagination\LengthAwarePaginator(array_values($items->forPage($page, $perPage)->toArray()), $items->count(), $perPage, $page, $options);
        //ref for array_values() fix: https://stackoverflow.com/a/38712699/3553367
    }

thank you 👍 👍

@jperalta-EndlessCodeStudio

Thank you very much. Saved my lyfe! 👍 👍

@Kaylakaze
Copy link

Kaylakaze commented Nov 5, 2020

Better yet, just make a macro.

Collection::macro('paginate', function($perPage = 15, $page = null, $options = []) {
            $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
            if (!isset($options['path'])) {
                $options['path'] = '/' . request()->path();
            }
            return new LengthAwarePaginator(array_values($this->forPage($page, $perPage)->toArray()), $this->count(), $perPage, $page, $options);
        });

@kanchanarandika
Copy link

Thank you very much! This is really helpful

@MarouanAfkir
Copy link

For those who has issues with second page:

where 2nd page data has keys like:

"data": {
    "5": {
    "userId": "564110eadcb39832268ea873",
    "email": "dsdfgdfg@il.com",
    "isActive": true,
    "firstName": "dsdfgdfg",
    "lastName": "dsdfgdfg",
    "permissionType": "dsdfgdfg"
    },
    "6": {
    "userId": "564110ea2169bc358a3b65c2",
    "email": "dsdfgdfg@d.com",
    "isActive": false,
    "firstName": "dsdfgdfg",
    "lastName": "dsdfgdfg",
    "permissionType": "dsdfgdfg"
    },
    "7": {
    "userId": "564110eaee662f30c4bd6772",
    "email": "dsdfgdfg@dsdfgdfg.com",
    "isActive": true,
    "firstName": "dsdfgdfg",
    "lastName": "dsdfgdfg",
    "permissionType": "dsdfgdfg"
    },
}

This is because forPage() returns an array with keys

Fix is to add array_values():

  public function paginateCollection($items, $perPage = 15, $page = null, $options = [])
    {
        $page = $page ?: (\Illuminate\Pagination\Paginator::resolveCurrentPage() ?: 1);
        $items = $items instanceof \Illuminate\Support\Collection ? $items : \Illuminate\Support\Collection::make($items);
        return new \Illuminate\Pagination\LengthAwarePaginator(array_values($items->forPage($page, $perPage)->toArray()), $items->count(), $perPage, $page, $options);
        //ref for array_values() fix: https://stackoverflow.com/a/38712699/3553367
    }

Thanks, mate

@Tuhedul-Islam
Copy link

/**

  • Gera a paginação dos itens de um array ou collection.
  • @param array|Collection $items
  • @param int $perPage
  • @param int $page
  • @param array $options
  • @return LengthAwarePaginator
    */
    public function paginate($items, $perPage = 2, $page = null)
    {
    $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
    $items = $items instanceof Collection ? $items : Collection::make($items);
    return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, [
    'path' => Paginator::resolveCurrentPath(),
    'pageName' => 'page',
    ]);
    }

Thanks a lot

@mosesegboh
Copy link

please how can it be installed??

@Kaylakaze
Copy link

Depends on which one you're talking about. For the macro, you put it in your boot() method on AppServiceProvider (or on another service provider if you want). For the general method, you specify a custom collection object for your model and put it on the custom collection.

@cnyambo
Copy link

cnyambo commented Mar 8, 2021

With the same code, I have two pages, one for search where I enter the search criteria and another to display the results. However, when I click to the second or any other page, the system redirect me first to the search page again to reenter the search criteria then bring the result for that specific page. Could you please help to solve this?

@Sarmed-armis
Copy link

great for this comments thanks to all

@Gab-Arruda
Copy link

Great!! It works just fine. Thanks a lot!!!

@mdbtekny
Copy link

Hello to everyone, how can i use ->links()? Thanks in advance

@vladimir-zarcanin
Copy link

If you have a problem with pagination add values() method:
return new LengthAwarePaginator($items->forPage($page, $perPage)->values(), $count, $perPage, $page, []);

@Tuhedul-Islam
Copy link

Tuhedul-Islam commented Feb 17, 2022 via email

@vladimir-zarcanin
Copy link

I have a problems when fetch page > 1, $items->forPage($page, $perPage)->values(). this solved my problems.

@NaungYeHtet
Copy link

This type of pagination can impact performance?

@Kings-Israel
Copy link

Thanks very much

@waiylkarim
Copy link

waiylkarim commented Mar 7, 2023

Laravel 9.x and above

	public static function paginate(array|Collection $items, mixed $perPage = null, mixed $page = null, array $options = [], mixed $path = null)
	{
		$perPage = is_null($perPage) ? 25 : $perPage;
		
		$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
	
		$items = $items instanceof Collection ? $items : Collection::make($items);
	
		$paginator = new LengthAwarePaginator(
			$items->forPage($page, $perPage), 
			$items->count(), 
			$perPage, 
			$page, 
			$options
		);

		if(!is_null($path)) {
			$paginator->setPath($path);
		}

		return $paginator;
	}

Basic Example:

        // set path dynamically from current route name or url with params
        $path = route(request()->route()->getName(), $request->except(['page']));
        
        $invoices = YOUR_HELPER_CLASS_HERE::paginate(
            items: $data, 
            perPage: 10, 
            path: $path
        );

@masroore
Copy link

masroore commented Aug 27, 2023

Laravel 10.x / PHP 8.2 and above:

public static function paginate(
	array|Collection $items,
	?int $perPage = null,
	?int $page = null,
	array $options = [],
	?string $path = null
): LengthAwarePaginator {
	$perPage ??= 50;
	$page ??= Paginator::resolveCurrentPage(default: 1);
	$path ??= Paginator::resolveCurrentPath();

	$items = $items instanceof Collection ? $items : Collection::make($items);

	$paginator = new LengthAwarePaginator(
		$items->forPage($page, $perPage),
		$items->count(),
		$perPage,
		$page,
		$options
	);

	if (!blank($path)) {
		$paginator = $paginator->setPath($path);
	}

	return $paginator;
}

Usage:

$paginated_list = Helper_Class::paginate($list_of_items);

@ofumbi
Copy link

ofumbi commented Feb 10, 2024

Collection::macro('paginate', function($perPage = 15, $page = null, $options = []) {
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
if (!isset($options['path'])) {
$options['path'] = '/' . request()->path();
}
return new LengthAwarePaginator(array_values($this->forPage($page, $perPage)->toArray()), $this->count(), $perPage, $page, $options);
});

Failed in L10
Place this in the boot method of your App\Providers\AppServiceProvider;

 Collection::macro('paginate', function ($perPage = 15, $page = null, $options = []) {
    $page = $page ?: (\Illuminate\Pagination\Paginator::resolveCurrentPage() ?: 1);
    return new \Illuminate\Pagination\LengthAwarePaginator(array_values($this->forPage($page, $perPage)->toArray()), $this->count(), $perPage, $page, $options);
});

Use like this

$perPage = 5;
collect([1,2,3,4,5])->paginate($perPage)

@mickela
Copy link

mickela commented Feb 26, 2024

Great, thanks! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment