Flysystem s3: невозможно переместить каталог

Я использую пакет league/flysystem с драйвером Flystem на laravel.

В настоящее время я пытаюсь переименовать каталог. Насколько я понимаю, для этого мне нужно использовать метод move(). В драйвере локальной файловой системы это работает нормально. Однако при использовании s3 я получаю следующую ошибку:

"Error executing "GetObjectAcl" on "https://asgard-modules-dev.s3-eu-west-1.amazonaws.com/assets/media/test-s3?acl"; 

AWS HTTP error: Client error: `GET https://asgard-modules-dev.s3-eu-west-1.amazonaws.com/assets/media/test-s3?acl` resulted in a `404 Not Found` response:↵
<?xml version="1.0" encoding="UTF-8"?>↵

<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message> (truncated...)↵ 

NoSuchKey (client): The specified key does not exist. - <?xml version="1.0" encoding="UTF-8"?>↵

<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>assets/media/test-s3</Key><RequestId>B50AF4134D66FA68</RequestId><HostId>yliO7CUIt5PBsix/C339BrdFzrMTsKsommGc0fVOculaITBfC9CDPg2X43oXnW9RjnvRynmi39k=</HostId></Error>"

Когда я выгружаю свои пути from и to, у меня есть правильные имена путей:

"/assets/media/test-s3" (from)
"/assets/media/test-s3333" (to)

Путь from существует в этом месте.

Я что-то упускаю?

Спасибо!


person Nicolas Widart    schedule 28.09.2017    source источник
comment
Для чего нужен запрос acl в конце? См. этот stackoverflow.com/questions/44778448/   -  person Jonathan    schedule 28.09.2017
comment
Я не знаю, я подозреваю, что это может быть возможной причиной. URL генерируется Flystem с адаптером s3.   -  person Nicolas Widart    schedule 28.09.2017
comment
Трудно сказать, что именно происходит, но объекты-заполнители для каталогов в S3 заканчиваются на /... если они вообще присутствуют (в этом нет необходимости)... Так что вы можете< /i> необходимо использовать ...test-s3/. Однако... Объекты S3 в каталоге на самом деле ни к чему. Каталоги не являются контейнерами в S3, как в файловых системах.   -  person Michael - sqlbot    schedule 29.09.2017
comment
Проблема здесь в том, что S3 на самом деле не имеет каталогов, и поэтому их нельзя перемещать. Это техническое ограничение системы S3, которое Flysystem не может обойти. Единственное решение — вручную создать новый путь и переместить все файлы по одному с одного пути на другой.   -  person Surya    schedule 27.01.2020


Ответы (1)


Поскольку S3 не позволяет вам перемещать каталоги (поскольку они на самом деле не являются каталогами), вам нужно вручную переместить все файлы внутри и удалить старый каталог.

Вот пример кода моего решения:

class S3BucketService
{
    const SERVICE = 's3';

    /**
     * @param string $from
     * @param string $to
     * @return bool
     */
    public static function moveDirectory(string $from, string $to)
    {
        if (Storage::disk(static::SERVICE)->has($from)) {
            $folderContents = Storage::disk(static::SERVICE)->listContents($from, true);
            foreach ($folderContents as $content) {
                if ($content['type'] === 'file') {
                    $src  = $content['path'];
                    $dest = str_replace($from, $to, $content['path']);
                    Storage::disk(static::SERVICE)->move($src, $dest);
                }
            }

            Storage::disk(static::SERVICE)->deleteDirectory($from);
        }
    }
}

В этом примере у меня есть папка проекта, и все файлы будут вложены туда.

$from будет выглядеть примерно так: projectId имя_проекта/документы

$to будет выглядеть примерно так: projectId имя_проекта/OtherDocumentFolder

Примечание: константа SERVICE также является необязательной, но в моем проекте я подключаюсь к нескольким облачным службам хранения, и этот класс расширяет другой и переопределяет SERVICE из родительского класса.

person Surya    schedule 27.01.2020