symfony中flysystem组件如何获取特定的文件存储服务

How get specific file storage service in flysystem component in symfony

我只是想知道如何在 flysystem 包中获取指定的文件存储实例。 例如,如果我有这样的配置:

flysystem:
    storages:
        first.storage:
            adapter: 'local'
            options:
                directory: '%kernel.project_dir%/var/storage/storage/first'
        second.storage:
            adapter: 'local'
            options:
                directory: '%kernel.project_dir%/var/storage/default/second'

我想根据工厂中的某些参数来获取它。类似的东西:

$fileSystemStorage = (new FileSystemFactory()->getStorage('second');

这是我的工厂:

class FileSystemFactory
{
    public function getStorage(string $storage): FilesystemOperator
    {
        switch ($storage) {
            case 'first':
                break;
            case 'second':
                break;
        }
    }
}

我只是不知道如何手动定义我想从中获取的选项 flysystem.yaml。

在文档中它说我可以注入它类似的东西(来自配置的名称 camelcase): https://github.com/thephpleague/flysystem-bundle

public function __construct(FilesystemOperator $firstStorage)
{
    $this->storage = $firstStorage;
}

但在我的例子中,我想根据参数手动定义它。 当然,我可以创建两个 类,它们有 2 个不同的注入($firstStorage 和 $secondStorage),而不是那些 类 中的 return 个对象,但也许有一些更简单的方法?

如果您阅读了 FlySystemBundle 的文档,您会发现它支持在运行时延迟加载存储:

Link to the docs

如果通过 ENV 变量(或参数)设置此设置不能满足您的需求,您可以利用 LazyFactory 本身并通过 Lazyfactory::createStorage 方法直接使用它。

如果这不符合您的需要,您可以复制 class 并分配给它 CompilerPass 并根据需要进行配置。

已更新!!!

我遇到了非常相似的问题,我通过使用 ContainerInterface 和服务别名解决了它(flysystem 服务不是 public):

// config/services.yaml
services:
// ...
    // we need this for every storage, 
    // flysystems services aren't public and we can solve this using aliases
    first.storage.alias:
        alias: 'first.storage'
        public: true
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;

class FileSystemFactory
{
    private $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function getStorage(string $storage)
    {
        $storageContainer = $this->container->get($storage); // ex. first.storage.alias

        switch ($storageContainer) {
            case 'first':
                break;
            case 'second':
                break;
        }
    }
}