Laravel league / flysystem получение URL файла с AWS S3

Я пытаюсь построить систему управления файлами в Laravel на основе league/ flysystem:https://github.com/thephpleague/flysystem

Я использую адаптер S3, и он работает для сохранения загруженных файлов с помощью:

$filesystem->write('filename.txt', 'contents');

теперь я застрял на генерации загрузить URL файла при использовании адаптера S3.

файлы сохраняются правильно в S3 ведро, у меня есть разрешения на доступ к ним, я просто не знаю как чтобы добраться до Метода S3 getObjectUrl через пакет league/flysystem.

Я пробовал:

$contents = $filesystem->read('filename.txt');

но это возвращает содержимое файла.

$contents = $filemanager->listContents();

или

$paths = $filemanager->listPaths();

но они дают мне относительные пути к моим файлам.

мне нужно что-то вроде "ht...//[S3-region].amazonaws.com/[ведро] / [реж.] / [файл]..."

5 ответов


Я не уверен, что правильно способ сделать это с Flysystem, но основной S3Client у объекта есть метод для этого. Вы могли бы сделать $filesystem->getAdapter()->getClient()->getObjectUrl($bucket, $key);. Конечно, создание URL-адреса так же тривиально, как вы описали, поэтому вам не нужен специальный метод для этого.


Я использую Laravel 5.2, и код ниже, казалось, работал нормально.

Storage::cloud()->url('filename');

при обновлении до Laravel 5.1 этот метод больше не поддерживается адаптером. Нет в вашей конфигурации у вас должен быть набор S3_REGION или вы получите недопустимую ошибку имени хоста, а во-вторых, мне пришлось использовать команду в качестве ввода для создания presignedRequest.

    public function getFilePathAttribute($value)
{

    $disk = Storage::disk('s3');
    if ($disk->exists($value)) {
        $command = $disk->getDriver()->getAdapter()->getClient()->getCommand('GetObject', [
            'Bucket'                     => Config::get('filesystems.disks.s3.bucket'),
            'Key'                        => $value,
            'ResponseContentDisposition' => 'attachment;'
        ]);

        $request = $disk->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');

        return (string) $request->getUri();
    }

    return $value;
}

возможно, я немного опоздал на этот вопрос, но вот способ использовать встроенную файловую систему Laravel 5.

Я создал класс Manager, который расширяет FilesystemManager Laravel для обработки общедоступного извлечения url:

class FilesystemPublicUrlManager extends FilesystemManager
{

    public function publicUrl($name = null, $object_path = '')
    {
        $name = $name ?: $this->getDefaultDriver();
        $config = $this->getConfig($name);

        return $this->{'get' . ucfirst($config['driver']) . 'PublicUrl'}($config, $object_path);
    }

    public function getLocalPublicUrl($config, $object_path = '')
    {
        return URL::to('/public') . $object_path;
    }

    public function getS3PublicUrl($config, $object_path = '')
    {
        $config += ['version' => 'latest'];

        if ($config['key'] && $config['secret']) {
            $config['credentials'] = Arr::only($config, ['key', 'secret']);
        }

        return (new S3Client($config))->getObjectUrl($config['bucket'], $object_path);
    }
}

затем я добавил этот класс В AppServiceProvider под методом register, чтобы он имел доступ к текущему экземпляру приложения:

$this->app->singleton('filesystemPublicUrl', function () {
    return new FilesystemPublicUrlManager($this->app);
});

наконец, для легкого статического доступа я создал класс фасада:

use Illuminate\Support\Facades\Facade;

class StorageUrl extends Facade
{

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'filesystemPublicUrl';
    }
}

Сейчас, Я можно легко получить общедоступный url-адрес для моих общедоступных объектов в локальной файловой системе и файловой системе s3 (обратите внимание, что я ничего не добавил для ftp или rackspace в FilesystemPublicUrlManager):

$s3Url = StorageUrl::publicUrl('s3') //using the s3 driver
$localUrl = StorageUrl::publicUrl('local') //using the local driver
$defaultUrl = StorageUrl::publicUrl() //default driver
$objectUrl = StorageUrl::publicUrl('s3', '/path/to/object');

другая форма хранения:: cloud ():

    /** @var FilesystemAdapter $disk */
    $s3 = Storage::disk('s3');
    return $s3->url($path);