Flysystem s3:无法移动目录

时间:2017-09-28 18:15:31

标签: php laravel amazon-s3 flysystem

我在laravel上使用带有Flystem驱动程序的league/flysystem包。

我目前正在尝试重命名目录。根据我的理解,我需要使用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>"

当我转储fromto路径时,我有正确的路径名称:

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

from路径确实存在于该位置。

我错过了什么吗?

谢谢!

1 个答案:

答案 0 :(得分: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 projectname / Documents

$ to将类似于 projectId projectname / OtherDocumentFolder

注意:SERVICE常量也是可选的,但是在我的项目中,我正在连接到多个云存储服务,并且该类扩展了另一个云存储服务,并从父类覆盖了SERVICE。