ThinkPHP不直接支持按二级域名生成独立静态HTML,需通过域名识别构造专属路径(如/static/news/article/123.html),在控制器中用view()->fetch()渲染后file_put_contents()写入,并确保Nginx配置匹配多级路径直出。

ThinkPHP 本身不直接支持“按二级域名生成独立静态 HTML 文件”,但可以通过控制器逻辑 + 域名识别 + 路径隔离,实现不同二级域名(如 news.example.com、blog.example.com)各自生成、读取、更新互不干扰的静态 HTML 缓存。核心不是改框架配置,而是把域名作为缓存路径或文件名的一部分。
1. 域名识别与路径隔离
在生成或读取静态 HTML 前,先获取当前请求的二级域名,并据此构造专属缓存路径:
- 用
$_SERVER['HTTP_HOST']或request()->host()获取完整域名 - 提取二级域名前缀(如从
news.example.com提取news),可用正则:preg_match('/^([a-z0-9\-]+)\.example\.com$/', $host, $matches); $subdomain = $matches[1] ?? 'www'; - 将子域名融入静态文件路径,例如:
$htmlPath = public_path() . '/static/' . $subdomain . '/article/' . $id . '.html';
2. 静态生成逻辑必须放在控制器中
别依赖中间件或自动缓存机制——它们无法安全终止流程,也拿不到模板上下文。正确做法是手动控制「判断→渲染→写入→退出」:
- 检查目标 HTML 文件是否存在且未过期(用
filemtime()对比) - 若需生成:调用
view()->fetch('article/detail', $data)渲染为字符串 - 确保模板内所有资源引用为绝对路径(如
/static/css/app.css),否则离线 HTML 会失效 - 创建目录(
mkdir(dirname($htmlPath), 0755, true)),再写入:file_put_contents($htmlPath, $htmlContent); - 最后用
readfile($htmlPath); exit;直接输出并终止 PHP 执行
3. 避免规则冲突:URL → 文件名要唯一
同一页面不同参数(如分页、筛选)必须生成不同文件,否则内容覆盖错乱:
立即学习“PHP免费学习笔记(深入)”;
- 不要只用
{id}命名,应包含完整查询参数哈希:$filename = md5(request()->url(true)) . '.html'; - 或结构化拼接:
$htmlPath = public_path() . '/static/' . $subdomain . '/list/p' . $page . '_s' . $sort . '.html'; - 更新时先
unlink()旧文件,避免磁盘占满;不要依赖“覆盖写入”
4. Nginx 配置需匹配多级路径
Web 服务器必须能直出所有子域名下的静态文件,不能只配 /static/ 一级:
- 在 Nginx server 块中加:
location ^~ /static/ { alias /path/to/public/static/; expires 1h; } - 若路径含子域名目录(如
/static/news/...),确保该路径真实存在且权限正确(web 用户可读) - 伪静态规则也要兼容子域名上下文,例如:
rewrite ^/article/(\d+)\.html$ /index.php?s=/article/detail/id/$1 last;→ 改为按 host 动态路由,或统一由 PHP 入口接管



















