准备工作
这里就不具体教各位怎么准备了,相信大家都会。
- Flarum 的 FoF Upload 插件:
composer require fof/upload:"*"
- Flarum 的 AWS S3 协议:
composer require league/flysystem-aws-s3-v3:1.*
- 腾讯云对象存储的存储桶(公开读私有写)
- 腾讯云的 API 秘钥:https://console.cloud.tencent.com/cam/capi
配置上传插件
这个部分的最下面有一张插件配置的总览图。
进入 Flarum 后台,启用 FoF Upload 并把上传方式都改为“AWS S3 或 S3 兼容”。

还是插件配置界面,拉到最下面把“存储设置”里的“文件链接前缀”改成你的存储桶的访问域名。
在腾讯云后台的存储桶的“配置管理”右下角可以找到默认访问域名。由于默认域名有一些限制(任意类型文件不支持预览,apk、ipa 类型文件不支持下载),所以有已备案域名的话可以配置一个自定义源站域名。

在“AWS S3 存储设置”处填写“Key”和“Secret”,分别为腾讯云 API 访问秘钥的“SecretId”和“SecretKey”。
“存储空间(Bucket)”字段留空,原因会在第 8 步提到。
“地域(Region)”字段对应的数据可以在存储桶的“配置管理”左上角找到,填写上去。

在“高级 S3 存储设置”处填写“访问域名(Endpoint)”,格式为 https://存储桶名称.cos.地域.myqcloud.com
,然后把下面的“使用 path-style 访问域名”勾选上。
虽然腾讯云禁止使用“path-style 域名”进行读写,但实际上这个并不算,所以可以正常用。存储桶名称可以在腾讯云后台的“存储桶列表”找到。

“访问控制列表(ACL)”字段填写为 public-read
。
点击最下面的“保存”按钮保存设置。
到这里配置还并未完成。刚才在第 4 步时我们留空了“存储空间(Bucket)”字段,这样是无法使用的。但如果你“正确”填写了这个字段,就会发现你上传文件的链接实际上是 https://访问域名/存储桶名称/日期/文件名
。而 Flarum 上传完文件后自动生成的链接里并没有“存储桶名称”那个部分,所以没法正常用。要解决这个问题,需要前往你的网站服务器后台,修改插件的代码。
打开网站服务器后台,在 Flarum 安装目录下找到 vendor/aws/aws-sdk-php/src/InputValidationMiddleware.php
并打开。
把第 62 行到第 67 行删掉。
if ($argument === '' || $argument === null) {
$commandName = $cmd->getName();
throw new \InvalidArgumentException(
"The {$commandName} operation requires non-empty parameter: {$member}"
);
}
由于这个插件本质上还是以 AWS S3 为标准设计,所以配置时必须要填写“存储空间”字段,但这样的话,腾讯云对象存储里就会多一个没有意义的文件夹。因此刚才在第 4 步留空,并且在第 6 步直接包含了存储桶名称以供读写。
完成!
附录:FoF Upload 插件配置一览。

资源迁移
如果你的网站是新部署的,以前没有文件的话,那么在刚才就已经结束了。但我是先开的网站,后弄的对象存储,所以我的网站里还有需要迁移过去的资源文件。
如果你嫌麻烦的话,也可以不做这个操作。但我的目的之一是给服务器减小压力,所以要把现有的文件迁移过去。
打开网站服务器后台,在 Flarum 安装目录下找到 public/assets/files
文件夹。里面应该是一些以日期为名的文件夹,把那些文件夹全部复制到你的对象存储里去。
打开数据库管理后台(比如 phpMyAdmin,或者直接开 SQL 控制台),运行以下 SQL 语句:
UPDATE posts SET content = REPLACE(content, 'https://网站域名/assets/files/', 'https://对象存储访问域名/');
UPDATE fof_upload_files SET url = REPLACE(url, 'https://网站域名/assets/files/', 'https://对象存储访问域名/');
以上两条语句分别会把现有帖子的文件链接替换,并把用户媒体管理器的链接改掉。如果你安装网站时设置了数据库前缀,需要在 posts
和 fof_upload_files
的前面加上你的前缀。
完成!