Laravel league / flysystem получает URL-адрес файла с AWS S3

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

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

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

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

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

Я пытался:

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

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

 $contents = $filemanager->listContents(); 

или

 $paths = $filemanager->listPaths(); 

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

Мне нужно что-то вроде «ht … // [s3-region] .amazonaws.com / [bucket] / [dir] / [file] …"

Я не уверен, что правильный способ сделать это с помощью 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, который расширяет Laravel's FileystemManager для обработки общедоступного поиска 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 под регистрационным методом, чтобы он имел доступ к текущему экземпляру приложения:

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

Наконец, для простого статического доступа я создал класс 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'; } } 

Теперь я могу легко получить публичный 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');