直接运行 composer require league/flysystem 即可安装 Flysystem v3 最新版(如 3.29.0),无需指定版本号;但必须额外安装对应适配器(如 local 或 S3),且需正确构造 LocalFilesystemAdapter 并传入 Filesystem,路径须为绝对路径,跨存储同步须用 MountManager。

直接运行 composer require league/flysystem 就能装上 Flysystem v3 最新版,不需要加 ^3.0 或 v3 ——Composer 会自动选兼容当前 PHP 版本的最新稳定版(如 3.29.0)。
为什么不能只装 core 包就写文件?
Flysystem v3 把「适配器」和「文件系统实例」拆成两层,缺一不可:
-
league/flysystem只提供Filesystem类和核心接口,不带任何具体存储能力 - 必须额外装对应适配器包,比如本地用
league/flysystem-local,S3 用league/flysystem-aws-s3-v3 - 漏装适配器,或只 new 了适配器没传给
Filesystem构造函数,就会报错:TypeError: Argument 1 passed to League\Flysystem\Filesystem::__construct() must be an instance of League\Flysystem\AdapterInterface
本地开发最简验证流程
先跑通本地读写,再扩展其他存储,避免一上来就陷进 AWS 权限或 OSS 签名里:
- 执行
composer require league/flysystem league/flysystem-local - 代码里用
LocalFilesystemAdapter(注意不是LocalAdapter,那是 v1 的) - 路径必须是绝对路径,例如
/var/www/myapp/storage;./storage在 CLI 下可能凑合,Web 环境下因getcwd()不稳定极易失败 - 构造顺序不能错:
$adapter = new LocalFilesystemAdapter($path); $filesystem = new Filesystem($adapter);
跨存储同步别用 copy 方法硬搬
$filesystem->copy() 只支持同一实例内路径,比如 local://a.txt → local://b.txt。想从本地拷到 S3?必须用 MountManager:
- 先装两个适配器:比如
league/flysystem-local和league/flysystem-aws-s3-v3 - 构造
MountManager时传['local' => $localAdapter, 's3' => $s3Adapter] - 路径就得写成
local://file.txt和s3://bucket/key.txt,然后调$mountManager->copy('local://a.txt', 's3://b.txt') - 硬写
$localFs->copy('a.txt', 's3://b.txt')会直接报方法不存在或协议不识别
最常被跳过的一步是确认适配器类名和命名空间是否匹配当前版本——v3 的 LocalFilesystemAdapter 和 v1 的 LocalAdapter 完全不兼容,IDE 自动导入也容易导错,建议复制文档里的 use 语句再改路径。











