ThinkPHP分页对象在模板中可直接用{foreach $list item="vo"}遍历(TP6+支持自动解包),TP5.1需用{$list->items()}或{$list->toArray()};分页HTML必须调用{$list->render|raw}输出,不可解包或误用{$list|raw}。

ThinkPHP分页对象在模板里怎么直接 foreach?
不能直接 foreach 分页对象(比如 $list),它不是数组,而是 Paginator 实例。你看到的“数据”其实是它的 items 属性,但模板里不暴露该属性——必须用 $list->items() 或更常用的是直接用 $list 配合 foreach(ThinkPHP 6+ 已支持自动解包)。
常见错误是写成:{foreach $list item="vo"}...{/foreach} 却报错或空循环,原因往往是版本不匹配或没调用 render() 导致对象未完成初始化。
- ThinkPHP 6.0+:模板中
$list可直接用于{foreach},底层已实现ArrayAccess和IteratorAggregate - ThinkPHP 5.1:必须显式调用
$list->toArray()或$list->items(),否则foreach会失败 - 确保控制器里返回的是分页对象本身,不是
$list->items()提前取出来的数组(否则丢了分页信息)
模板里怎么输出分页 HTML?
分页链接不靠手拼,用 $list->render() 输出。它返回带样式的 HTML 字符串,包含上一页、下一页、页码跳转等。
注意:默认样式极简,且依赖内置 CSS 类(如 pagination),如果项目用了 Bootstrap 或 LayUI,得自定义渲染器,否则样式错乱或按钮不显示。
立即学习“PHP免费学习笔记(深入)”;
- 直接输出:
{$list->render()}(TP6 模板引擎语法) - TP5.1 用:
{$list->render|raw},避免 HTML 被自动转义 - 若要替换分页文字(如“首页”“尾页”),需在分页配置里设
page_show或继承Paginator重写getLinks() - 不要把
render()结果赋给变量再 echo,模板里直接调用最安全
为什么分页后数据总数对不上?
常见原因是查询时用了 limit 或 paginate(10, false) 的第二个参数为 false,跳过了 count 查询。TP 分页默认会执行两条 SQL:一条 COUNT,一条 SELECT。关掉 count 就没法算总页数,$list->lastPage() 和 $list->total() 都不准。
- 检查是否写了类似
$model->where(...)->paginate(15, false)——false表示不查总数,只分页数据 - 关联查询 + 分页时,
COUNT可能因GROUP BY或JOIN出错,此时应手动传入count值:paginate(15, false, ['query' => [...], 'total' => $manualCount]) - 使用
withCount()等聚合字段时,务必确认主表 count 不受子查询干扰
如何在模板里访问分页元信息?
除了遍历数据,常需显示“共 X 条,第 Y 页”,这些信息都挂在分页对象上,但命名和获取方式版本差异大。
- 当前页:
$list->currentPage()(TP6)或$list->currentPage(TP5.1,注意是属性非方法) - 每页条数:
$list->listRows(TP5.1)或$list->perPage()(TP6) - 总条数:
$list->total()(TP6)或$list->total(TP5.1) - 上一页 URL:
$list->appends($params)->previousPageUrl(),appends用于保留搜索参数 - 别直接读
$list->options,里面字段名不稳定,优先用公开方法
复杂点在于 TP5 和 TP6 的属性/方法混用容易出错,比如在 TP6 模板里写 $list->total 会报错,必须用 $list->total();而 TP5.1 写成 $list->total() 反而没这个方法。



















