多语言分页必须显式保留lang参数,否则翻页即回默认语言;ThinkPHP中需用request()->param()获取全部GET参数并剔除page后传入paginate()的query配置,同时SQL查询、缓存key、模板文案均须按语言隔离与翻译。

多语言分页必须显式保留语言参数,否则翻页就掉默认语言;伪静态下分页链接生成依赖正确 URL 重写和 query 配置,否则 $_GET 为空、条件丢失。
分页 URL 里怎么带 lang 参数不丢
ThinkPHP 的 paginate() 默认只读 $_GET['page'],不会自动继承 lang 或其他参数。你得手动透传:
- 用
request()->param()获取全部 GET 参数(含lang),再剔除page避免冲突:array_diff_key(request()->param(), ['page' => '']) - 传给
paginate()的query配置项:paginate(10, false, ['query' => array_diff_key(request()->param(), ['page' => ''])]) - 别用
input('lang')单独取值拼接——漏掉其他筛选条件(如 keyword、sort)时,翻页后搜索就清空了 - 如果用了路由变量(如
lang/:lang),确保query里也包含它,或改用appends(['lang' => $lang])显式追加
伪静态环境下分页链接生成失败
Nginx 没配对 try_files,会导致 $_GET 为空,paginate() 读不到当前页码,所有分页都跳回第 1 页。
- 确认 Nginx 配置含这行:
try_files $uri $uri/ /index.php?$query_string;—— 不能写成?_url=或省略$query_string - 检查 PHP 处理块是否设置了
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;,否则$_SERVER['QUERY_STRING']可能为空 - 伪静态后
request()->url()返回的仍是原始路径(如/zh/article?page=2),但实际请求是/zh/article/2,此时必须靠query配置把lang补回去,否则分页 HTML 里的 href 会丢语言 - 若路由定义了
lang为变量(如Route::get('article/:lang', 'Article/index')),控制器里需先取$lang = input('lang'),再在query中显式塞入
多语言内容查错:分页数据混着显示
数据库没加 WHERE lang = ?,中文用户翻到第 2 页可能看到英文文章——这不是前端过滤能解决的,是 SQL 层面隔离失效。
立即学习“PHP免费学习笔记(深入)”;
- 所有分页查询必须带语言条件:
Db::name('post')->where('lang', $lang)->where('status', 1)->paginate(10) - 模型查询同理:
PostModel::where('lang', $lang)->order('sort desc')->paginate(15) - 缓存 key 必须含语言标识,例如:
cache('posts_' . $lang . '_page_' . $page, $data),否则中英文用户共享同一份分页缓存 - 注意
paginate()内部会执行两次查询(COUNT 和 LIMIT),两次都得带上lang条件,框架会自动处理,你只需保证 where 链在paginate()前就已生效
分页模板里文案怎么翻译才不漏
ThinkPHP 自带的 render() 输出的是 HTML 字符串,里面的“上一页”“下一页”等文字是硬编码英文,多语言站点必须替换。
- 不要直接调用
{$list->render()},改用{$list->simple()}或自定义模板,把文案全换成__('Previous')、__('Page %d of %d', $current, $total) - 复制默认模板
vendor/topthink/framework/src/view/paginate.tpl到app/view/paginate.tpl,然后在config/app.php里配'template' => app_path() . 'view/paginate.tpl' - 检查所有占位符:
Page %d of %d、%d-%d of %d、省略号…对应的翻译字符串是否在.po文件里存在,漏一条,对应位置就显示英文 - 避免在模板里拼接:
"第" . $page . "页"→ 改用sprintf(__('Page %d'), $page)
最易被忽略的是:伪静态 + 多语言 + 分页三者叠加时,lang 既要出现在路由路径里,又要作为 query 参数透传给分页链接,二者缺一不可;少一个,翻页就断语言上下文。



















