用PHP实现分页功能
因为每次都要重新实现应用程序,所以变得很烦,所以我记下来了。
<?php
namespace App\Model;
trait BaseTrait
{
private static $instance;
private function __construct()
{
// new from private only
}
public static function getInstance()
{
if ( ! self::$instance)
{
self::$instance = new static();
}
return self::$instance;
}
}
<?php
namespace App\Model;
class Page
{
use BaseTrait;
private $page_unit;
private $default_page;
private $page_link;
private function __construct()
{
$this->setPageUnit(3);// 1ページに表示する件数
$this->setDefaultPage(1);// 最初のページ
$this->setPageLink(5);// ページネーションのリンクを表示する件数(中央をアクティブにしたいので奇数)
}
public function setPageUnit(int $number)
{
$this->page_unit = $number < 1 ? 1 : $number;
}
public function setDefaultPage(int $number)
{
$this->default_page = $number < 1 ? 1 : $number;
}
public function setPageLink(int $number)
{
$this->page_link = $number < 1 ? 1 : $number;
}
/**
* ページネーションの表示に必要な情報の取得
* これで取得したoffsetとlimitで表示するアイテムのリストは別途取得すること
*
* @param int $page ページ位置(クエリーストリングから渡ってくる想定)
* @param int $item_count 全アイテム数
* @return array
*/
public function getPageData(int $page = null, int $item_count): array
{
$item_count = $item_count < 1 ? 1 : $item_count;
$data = [];
$data['limit'] = $this->page_unit;
$data['max_page'] = (int)(($item_count - 1) / $this->page_unit) + 1;
if (is_null($page) || $page === 0 || $data['max_page'] < $page)
{
$data['current_page'] = $this->default_page;
$data['offset'] = 0;
}
else
{
$data['current_page'] = $page;
$data['offset'] = ($page - 1) * $this->page_unit;
}
$data['page_link'] = $this->page_link;
if ($data['current_page'] < $data['max_page'] - (int)($data['page_link'] / 2))
{
$start_number = $data['current_page'] - (int)($data['page_link'] / 2);
}
else
{
$start_number = $data['max_page'] - $data['page_link'] + 1;
}
$data['start_page'] = $start_number < $this->default_page ? $this->default_page : $start_number;
$data['pre_page'] = $data['start_page'] > 1 ? $data['start_page'] - 1 : null;
$end_number = $data['start_page'] + $data['page_link'] - 1;
$data['next_page'] = $end_number < $data['max_page'] ? $end_number + 1 : null;
return $data;
}
}
控制器
use App\Model\Page;
~~~~~~~~~~~~~~~~~~
$page = 処理;// クエリーストリングから取得(int|null)
$item_count = 処理;// DB等から対象データ件数取得(int)
$page_model = Page::getInstance();
$data['page_data'] = $page_model->getPageData($page, $item_count);
// DB等から$data['page_data']['offset']と$data['page_data']['limit']で表示データ取得
$data['item_object_list'] = 処理;
// $dataをテンプレートエンジンに渡す
在带有Bootstrap的模板引擎中显示
- blade
<div class="text-center">
<ul class="pagination">
@for ($i = $page_data['start_page']; $i < $page_data['start_page'] + $page_data['page_link']; $i++)
@if ($i > $page_data['max_page'])
@break
@endif
@if ($i === $page_data['current_page'])
<li class="active"><a href="?page={{ $i }}">{{ $i }}</a></li>
@else
<li><a href="?page={{ $i }}">{{ $i }}</a></li>
@endif
@endfor
</ul>
</div>
<!--ここにアイテム-->
<table class="table table-striped table-hover table-bordered">
<tr>
<th>ID</th>
<th>Name</th>
</tr>
@foreach ($item_object_list as $item_object)
<tr>
<td>{{ $item_object->id }}</td>
<td>{{ $item_object->name }}</td>
</tr>
@endforeach
</table>
- Smarty
<div class="text-center">
<ul class="pagination">
{for $i = $page_data['start_page'] to ($page_data['start_page'] + $page_data['page_link'] - 1)}
{if $i > $page_data['max_page']}
{break}
{/if}
{if $i === $page_data['current_page']}
<li class="active"><a href="?page={$i}">{$i}</a></li>
{else}
<li><a href="?page={$i}">{$i}</a></li>
{/if}
{/for}
</ul>
</div>
<!--ここにアイテム-->
<table class="table table-striped table-hover table-bordered">
<tr>
<th>ID</th>
<th>Name</th>
</tr>
{foreach from=$item_object_list item=item_object}
<tr>
<td>{$item_object->id}</td>
<td>{$item_object->name}</td>
</tr>
{/foreach}
</table>
※在创建向前或向后链接时,请使用$data[‘pre_page’]或$data[‘next_page’]。