从数据库动态生成导出页面:laravel-export 的 Exporter 类编程式配置完整指南
【免费下载链接】laravel-exportCreate a static site bundle from a Laravel app项目地址: https://gitcode.com/gh_mirrors/la/laravel-export
laravel-export 是 Laravel 生态中的静态站点导出工具——它会自动爬取你的应用,为每个 URL 生成一份静态 HTML,最终打包成一个可直接上传托管的静态站点。当导出页面需要从数据库动态获取时(比如"把全部已发布文章导出成静态页"),最灵活的方式不是改配置文件,而是注入Exporter 类,用代码编程式地配置导出内容。
为什么静态站点导出值得尝试 🚀
用 Laravel 写博客、文档站或内容站很方便,但托管起来要维护服务器、PHP 环境、数据库……而 laravel-export 让你"鱼和熊掌兼得":
- ✅保留 Laravel 开发体验:路由、Blade 模板、Eloquent 模型照用
- ✅输出一堆纯静态文件:丢到任意静态托管即可,快、省心、易扩展
- ✅适合内容型站点:后台管理 + 本地/远程服务器编辑,一键发布静态版
运行一次导出命令后,你会看到:
$ php artisan export Exporting site... Files were saved to disk `export`配置文件的局限:为什么需要编程式配置
laravel-export 默认通过config/export.php配置导出内容,核心选项有四个:
| 配置项 | 作用 | 默认值 |
|---|---|---|
crawl | 自动爬取站内所有链接并导出 | true |
paths | 手动指定要导出的 URL 路径 | [] |
include_files | 要打包进静态包的文件/目录(源路径 => 目标路径) | ['public' => ''] |
exclude_file_patterns | 排除匹配的正则文件模式 | ['/\\.php$/', '/mix-manifest\\.json$/'] |
配置文件适合"固定不变"的导出清单,但遇到这类需求就无能为力了:
- 把数据库中所有已发布文章的 URL 都导出成静态页
- 根据环境变量或运行时数据决定导出范围
- 不同环境下导出不同的路径集合
这时就需要用到 Exporter 类——它把上面所有配置项都暴露成了可链式调用的方法。
认识 Exporter 类:导出流程的总指挥
Exporter 是整个包的入口类,它内部维护 4 组状态:
cleanBeforeExport— 导出前是否清空目标目录crawl/useStreaming— 是否爬站、是否启用流式(省内存)paths— 要导出为 HTML 的路径列表includeFiles/excludeFilePatterns— 要打包的文件与排除规则
这个类由服务提供者注册为单例(见 ExportServiceProvider 中的singleton(Exporter::class)),并且启动时会自动把config/export.php里的值填充进去——代码中的配置与配置文件是叠加关系,而不是互相覆盖。
从数据库动态生成导出页面:核心场景 🔑
下面是一个典型的真实场景:博客每篇文章的 slug 存在数据库里,希望每次导出时把所有文章页都生成静态 HTML。只需在应用服务提供者中注入 Exporter:
// app/Providers/AppServiceProvider.php use App\Models\Post; use Spatie\Export\Exporter; public function boot(Exporter $exporter) { $exporter->crawl(false); // 关闭全站爬取,改用手动清单 $exporter->useStreaming(true); // 大站点建议开启流式处理 $exporter->paths(['', 'about', 'contact', 'posts']); $exporter->paths(Post::published()->pluck('slug')); // 从数据库动态取路径 }然后照常运行php artisan export,所有文章页就会按数据库现状被导出。
这个写法有几个值得注意的细节:
paths()支持累加:多次调用会合并结果(源码中使用array_merge),静态页面和动态查询结果可以分开写paths()接受数组或可变参数:两种写法都合法- 还有
urls()方法:如果你手头是完整 URL 而不是路径,urls()会自动剥掉域名前缀再交给paths()处理
Exporter 方法速查表
| 方法 | 参数 | 用途 | 新手建议 |
|---|---|---|---|
crawl() | bool | 开关自动爬取 | 有动态清单时设为false |
useStreaming() | bool | 流式爬取省内存 | 页面多时开启 |
paths() | 数组 / 可变参数 | 指定导出路径,可多次累加 | 数据库结果集直接传入 |
urls() | 数组 / 可变参数 | 传入完整 URL,自动转路径 | 数据来自绝对链接时用 |
includeFiles() | ['源路径' => '目标路径'] | 打包静态资源 | 默认已含public目录 |
excludeFilePatterns() | 正则数组 | 排除特定文件 | 默认排除.php文件 |
cleanBeforeExport() | bool | 导出前清空目标目录 | 建议保持true |
所有方法都返回$this,可以像上面那样链式书写,代码非常紧凑。
一次 export() 背后发生了什么?
调用$exporter->export()后(见 Exporter.php 第 100-125 行),导出器会按固定顺序派发 4 类任务:
- CleanDestination— 若开启了
cleanBeforeExport,先清空输出目录,保证包是"新鲜"的 - CrawlSite— 若开启了
crawl,从首页开始爬取站内链接并逐页落盘(由 Crawler/LocalClient 在本地直接处理请求,无需真正发 HTTP) - ExportPath— 对
paths中的每个路径模拟一次请求,把响应内容写成index.html。返回 200/301/302 视为成功,其他状态码会直接抛异常 - IncludeFile— 按
includeFiles递归复制静态资源,并套用excludeFilePatterns过滤
默认输出位置是项目根目录下的dist文件夹;如果想存到 S3 或其他磁盘,只需在config/filesystems.php定义一个 disk,并在config/export.php里设置'disk' => 'export'即可(见 config/export.php 注释)。
进阶技巧:钩子命令让发布全自动 🎯
配置文件还支持before/after钩子,在导出前后执行任意 shell 命令。常见组合拳:
// config/export.php return [ 'before' => [ 'assets' => '/usr/local/bin/yarn production', // 导出前编译前端资源 ], 'after' => [ 'deploy' => '/usr/local/bin/netlify deploy --prod', // 导出后自动部署 ], ];不想跑某个钩子?命令行加--skip-{钩子名}即可,例如php artisan export --skip-deploy;--skip-all则跳过全部。这意味着"数据库改内容 → 跑一条命令 → 线上静态站更新"的完整流水线可以完全自动化。
新手常见疑问 FAQ ❓
Q:爬取(crawl)和 paths 是互斥的吗?不是。两者会叠加生效:爬取导出的页面 +paths里指定的页面。如果你的页面都能被链接到,通常开crawl就够了;paths适合补充"链接不到的页面"或做纯动态清单。
Q:导出后 PHP 文件会混进包里吗?默认不会。exclude_file_patterns默认排除所有.php文件和mix-manifest.json,避免public/index.php这类入口文件被打包。
Q:为什么我改的代码没生效?注意配置文件与代码配置是叠加的:ExportServiceProvider启动时已把配置文件值灌入单例,boot()中再调用的方法会合并追加,而不是重置。所以"想完全覆盖配置"时,记得在代码里显式关闭冲突项(如crawl(false))。
总结
- 📌固定清单→ 用
config/export.php就够了 - 📌动态清单(数据库驱动)→ 注入 Exporter,用
paths()传入查询结果 - 📌大型站点→ 开启
useStreaming(true)控制内存 - 📌自动发布→ 配合
before/after钩子实现"一条命令上线"
laravel-export 的 Exporter 类把"导出什么"从静态配置变成了可编程的决策,这正是它从"博客导出小工具"升级为"内容管线组件"的关键。把数据库查询结果喂给paths(),你的 Laravel 应用就拥有了真正的静态站点发布能力。
【免费下载链接】laravel-exportCreate a static site bundle from a Laravel app项目地址: https://gitcode.com/gh_mirrors/la/laravel-export
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考