需手动集成Pagerfanta:一、用composer require pagerfanta/pagerfanta安装;二、创建ThinkPHPAdapter实现AdapterInterface对接查询;三、控制器中传入页码、构建适配器并初始化Pagerfanta;四、扩展DefaultView为ThinkPHPView定制HTML结构;五、通过闭包生成兼容ThinkPHP路由的分页链接。

如果您希望在ThinkPHP项目中使用Pagerfanta作为分页组件,但该库并非原生适配ThinkPHP,需手动集成适配器与视图层,则需通过Composer引入并桥接数据源。以下是实现此集成的具体步骤:
一、安装Pagerfanta核心库
Pagerfanta本身是框架无关的PHP分页库,不提供官方ThinkPHP绑定包,因此需直接安装其主库,并确保PHP版本兼容(建议 PHP >= 7.4)。安装后需自行编写适配器对接ThinkPHP的查询结果。
1、在ThinkPHP项目根目录执行Composer命令安装Pagerfanta主库:
2、运行以下命令(注意:使用pagerfanta/pagerfanta而非已废弃的whiteoctober/pagerfanta):
立即学习“PHP免费学习笔记(深入)”;
composer require pagerfanta/pagerfanta
3、确认vendor/pagerfanta/pagerfanta目录已成功生成,且自动加载机制生效。
二、创建ThinkPHP数据源适配器
ThinkPHP的查询结果(如Collection或数组)无法被Pagerfanta直接识别,必须实现Pagerfanta\Adapter\AdapterInterface以桥接数据。该适配器负责将ThinkPHP的count()与slice()逻辑封装为Pagerfanta可调用的接口。
1、在app/common/adapter/下新建文件ThinkPHPAdapter.php:
2、定义类并实现getNbResults()与getSlice()方法:
getNbResults()返回总记录数;getSlice($offset, $length)返回指定偏移与长度的子集
3、在适配器构造函数中接收ThinkPHP查询对象(如Query实例或预取的array),避免重复执行COUNT查询。
三、在控制器中初始化Pagerfanta实例
完成适配器后,需在控制器中组装分页上下文:注入当前页码、每页条数,并绑定适配器。Pagerfanta不依赖HTTP请求对象,页码需显式传入,通常从input('page')获取。
1、在控制器方法内获取当前页码,默认为1:
$currentPage = (int) input('page', 1);
2、构建ThinkPHP查询并获取总数(用于适配器初始化):
$query = Db::name('article')->where('status', 1); $total = $query->count();
3、实例化自定义适配器与Pagerfanta:
$adapter = new ThinkPHPAdapter($query, $total); $pagerfanta = new Pagerfanta($adapter);
4、设置分页参数:
$pagerfanta->setCurrentPage($currentPage); $pagerfanta->setMaxPerPage(15);
四、配置并渲染自定义分页视图
Pagerfanta默认不提供ThinkPHP模板引擎支持,需选择或编写适配think-template的视图类。推荐复用其内置的Twig风格模板逻辑,或基于DefaultView扩展输出纯HTML字符串供{:}解析。
1、创建app/common/view/ThinkPHPView.php,继承Pagerfanta\View\DefaultView:
2、重写render()方法,使生成的HTML符合ThinkPHP前端结构(如<ul class="pagination">):
3、在控制器中调用视图渲染:
$view = new ThinkPHPView(); $html = $view->render($pagerfanta, url('index/article', ['page' => '__page__']));
4、将$html赋值给模板变量并在视图中输出:
{$html|raw}
五、处理URL生成与路由兼容性
ThinkPHP的URL生成机制与Pagerfanta的占位符(如__page__)存在格式差异,需确保分页链接能正确匹配当前路由规则。若使用伪静态或模块化路由,需手动拼接URL而非依赖url()函数的自动替换。
1、禁用自动占位符替换,改用闭包方式生成每个页码链接:
$view->setRenderFunction(function ($page) { return url('index/article', ['page' => $page]); });
2、在自定义视图中调用该闭包生成<a href="...">标签:
3、确保当前控制器方法支持page参数接收,并对非数字值做容错处理(如intval(input('page')) ?: 1):
if ($currentPage



















