web-dev-qa-db-fra.com

Laravel Ligue/système de vol obtenir l'URL du fichier avec AWS S3

J'essaie de construire un système de gestion de fichiers dans Laravel basé sur league/flysystem: https://github.com/thephpleague/flysystem

J'utilise l'adaptateur S3 et je l'ai utilisé pour enregistrer les fichiers téléchargés à l'aide de:

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

Maintenant, je suis bloqué sur la génération de l'URL du fichier download lors de l'utilisation de l'adaptateur S3.

Les fichiers sont correctement enregistrés dans le compartiment S3. J'ai les autorisations pour y accéder. Je ne sais tout simplement pas comment accéder à la méthode S3 getObjectUrl via le package league/flysystem.

J'ai essayé:

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

mais cela retourne le contenu du fichier.

$contents = $filemanager->listContents();

ou

$paths = $filemanager->listPaths();

mais ils me donnent les chemins relatifs à mes fichiers.

Ce dont j'ai besoin, c'est quelque chose comme "ht ... // [s3-region] .amazonaws.com/[bucket]/[dir]/[fichier] ..."

12
Ioana Cucuruzan

Je ne suis pas sûr de la manière dont correct est de le faire avec Flysystem, mais l’objet S3Client sous-jacent possède une méthode pour le faire. Vous pourriez faire $filesystem->getAdapter()->getClient()->getObjectUrl($bucket, $key);. Bien sûr, la construction de l'URL est aussi triviale que vous l'avez décrite, vous n'avez donc pas besoin d'une méthode spéciale pour le faire.

11
Jeremy Lindblom

J'utilise Laravel 5.2 et le code ci-dessous semble bien fonctionner.

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

Lors de la mise à jour vers Laravel 5.1, cette méthode n'est plus prise en charge par l'adaptateur. Non, dans votre configuration, vous devez avoir le jeu S3_REGION ou vous obtiendrez une erreur de nom d'hôte invalide et deuxièmement, je devais utiliser la commande en tant qu'entrée pour créer la requête 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;
}
8
Richard McLain

Peut-être que je suis un peu en retard à cette question, mais voici une façon d'utiliser le système de fichiers intégré de Laravel 5.

J'ai créé une classe Manager qui étend FilesystemManager de Laravel pour gérer la récupération des URL publiques:

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);
    }
}

Ensuite, j'ai ajouté cette classe à AppServiceProvider sous la méthode register afin qu'elle ait accès à l'instance actuelle de l'application:

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

Enfin, pour un accès statique facile, j'ai créé une classe Facade:

use Illuminate\Support\Facades\Facade;

class StorageUrl extends Facade
{

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

Maintenant, je peux facilement obtenir l'URL publique de mes objets publics sur mes systèmes de fichiers locaux et s3 (notez que je n'ai rien ajouté pour ftp ou rackspace dans 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');
6
Kevin Lee

Une autre forme de stockage :: cloud ():

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