在Symfony的Flysystem组件中如何获取指定的文件存储服务?
实现方案
你可以通过以下两种简便方式实现动态获取Flysystem存储实例,不需要单独为每个存储创建对应类。
方案1:固定存储场景(简单直接)
如果你的存储配置不会频繁新增,直接通过构造方法注入所有需要的存储实例,在工厂内做匹配返回即可:
<?php namespace App\Factory; use League\Flysystem\FilesystemOperator; class FileSystemFactory { public function __construct( private readonly FilesystemOperator $firstStorage, private readonly FilesystemOperator $secondStorage ) {} public function getStorage(string $storage): FilesystemOperator { return match($storage) { 'first' => $this->firstStorage, 'second' => $this->secondStorage, default => throw new \InvalidArgumentException(sprintf('存储%s不存在', $storage)) }; } }
注意:不要手动
new FileSystemFactory(),该工厂需要作为Symfony服务注入到你需要使用的类中,Symfony会自动为你注入对应存储实例。
方案2:动态扩展场景(推荐)
如果后续会频繁新增存储配置,可以用Symfony的标签定位器自动加载所有Flysystem存储,新增存储无需修改工厂代码:
<?php namespace App\Factory; use League\Flysystem\FilesystemOperator; use Symfony\Component\DependencyInjection\Attribute\TaggedLocator; use Symfony\Component\DependencyInjection\ServiceLocator; class FileSystemFactory { public function __construct( #[TaggedLocator('flysystem.storage')] private readonly ServiceLocator $storageLocator ) {} public function getStorage(string $storageName): FilesystemOperator { // 拼接Flysystem Bundle生成的服务ID,和你yaml中配置的存储名对应 $serviceId = sprintf('flysystem.storage.%s.storage', $storageName); if (!$this->storageLocator->has($serviceId)) { throw new \InvalidArgumentException(sprintf('存储%s不存在', $storageName)); } return $this->storageLocator->get($serviceId); } }
使用示例
在需要用到存储的类中注入FileSystemFactory即可调用:
// 控制器或其他服务中 public function upload(FileSystemFactory $fileSystemFactory) { $storage = $fileSystemFactory->getStorage('second'); // 执行文件操作 $storage->write(...) }
内容的提问来源于stack exchange,提问作者Andrii Sukhoi
相关产品推荐
相关产品推荐

