本质是paginate()未显式传递year/cat等归档参数到query选项,导致首页链接丢失筛选条件;必须用array_filter过滤后传入query,并确保where条件与之严格对应。

ThinkPHP分页跳转第一页链接异常,本质是 paginate() 生成的首页 URL 没有正确携带当前请求的所有有效查询参数,导致点击“首页”后条件丢失、数据重置。这不是模板渲染问题,而是分页逻辑层参数透传缺失。
为什么首页链接总是丢 year/cat/keyword 等参数
ThinkPHP 的 paginate() 默认只识别 page 参数,其他 GET 参数(如 ?year=2023&cat=tech)不会自动注入到分页链接中。首页链接(page=1)生成时若未显式传递这些参数,就会变成干净但错误的 /archive?page=1,而非预期的 /archive?year=2023&cat=tech&page=1。
-
query配置项必须显式传入,不能依赖框架自动推导 - 直接用
request()->param()会带入所有参数(包括空值),需先用array_filter()清理无效项 - 如果用了伪静态路由(如
/archive/2023/tech),要确保这些路径参数已解析并写入$_GET,否则request()->param()取不到
paginate() 调用时必须传 query 参数
在控制器中调用 paginate() 时,第三个参数必须是包含 query 键的配置数组,且该键值应为过滤后的当前请求参数。
- 错误写法:
$list = Article::where($where)->paginate(10);(无 query,首页链接必丢参) - 正确写法:
$list = Article::where($where)->paginate(10, false, ['query' => array_filter(input('get.'))]); - 若用 Db 门面:
Db::name('article')->where($where)->paginate(10, false, ['query' => request()->only(['year', 'cat', 'keyword'])]); - 注意:第二个参数设为
false是为了关闭总数统计(可选,但能提升深分页性能)
appends() 和 query 同时存在时的优先级陷阱
如果既在 paginate() 中传了 query,又对分页对象调用 appends(),同名键会被 appends() 覆盖——这容易导致首页链接参数被意外替换或覆盖。
- 例如:
paginate(10, false, ['query' => ['year'=>2023]])->appends(['year'=>2024]),首页链接会是?year=2024&page=1 - 固定参数(如
site_id)适合用appends();动态筛选参数(year/cat)必须走query -
appends()必须在 assign 到模板前调用,否则视图里render()不生效
伪静态下如何保证首页链接含参数
当使用路由规则将 /archive/:year/:cat 映射为 ?year=:year&cat=:cat 时,框架未必自动填充 $_GET。必须确认路由定义中启用了参数自动注入。
- 检查
route/app.php是否有类似['ext' => 'html', 'convert' => true]配置 - 在控制器开头加
dump(request()->param());确认year和cat是否在输出中 - 若没有,手动补全:
$params = array_merge(request()->param(), ['page' => input('page', 1)]); $list->appends($params); - 更稳妥的做法:统一用
request()->only(['year', 'cat', 'keyword'])替代input('get.'),避免取到未定义键
首页链接异常最常被忽略的一点:不是模板没写对,而是控制器里那行 paginate() 调用漏了 query。只要参数没进 query,后续所有链式操作都救不回来。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











